首页 > 解决方案 > 为什么我不能在我的 swift 代码中返回不透明类型?我已经返回符合该协议的类型

问题描述

图片

如图所示,我已经在使用MilkChocolate符合“ Chocolate”协议的类型,并且我试图声明一个返回“ some chocolate”的函数,这意味着返回一种巧克力类型取决于输入,但它给出我一个错误说
Function declares an opaque return type, but the return statements in its body do not have matching underlying types
这让我很困惑,我认为这MiklChocolateChocolate协议的底层类型有
什么问题?
我的代码应该与本教程相匹配:https
://docs.swift.org/swift-book/LanguageGuide/OpaqueTypes.html PS:如果您无法查看图像,这是代码

protocol Chocolate {
    associatedtype Content
    var mass:Double {get}
}

struct Honey {}
struct Milk {}
struct Wine {}

class HoneyChocolate: Chocolate {
    typealias Content = Honey
    var mass = 1.0
}

class MilkChocolate: Chocolate {
    typealias Content = Milk
    var mass = 1.2
    var mysteriousEffect = true
}

class WineChocolate: Chocolate {
    typealias Content = Wine
    var mass:Double = 999
}

func giveMeChocolate(of type:String) -> some Chocolate {
    switch type {
    case "honey":
        return HoneyChocolate()
    case "milk":
        return MilkChocolate()
    default:
        return WineChocolate()
    }
}

标签: swift

解决方案


出现问题是因为 Swift 不能返回不同类型的泛型类型。HoneyChocolate 和 WineChocolate 是不同的类型,这会导致问题。

class实现目标的另一种方法是返回一个Chocolate.

首先让我们声明我们的枚举风格:

enum Flavor {
    case Honey, Milk, Wine
}

然后我们将声明超类 Chocolate:

class Chocolate {
    var flavor: Flavor
    var mass:Double
    init(_ flavor: Flavor ,_ mass: Double) {
        self.flavor = flavor
        self.mass = mass
    }
}

现在我们可以继承这个类:

class HoneyChocolate: Chocolate {
    init() {
        super.init(Flavor.Honey, 1.0)
    }
}

class MilkChocolate: Chocolate {
    init() {
        super.init( Flavor.Milk, 1.2)
        var mysteriousEffect = true
    }
}

class WineChocolate: Chocolate {
    init() {
        super.init( Flavor.Wine, 999)
        var mysteriousEffect = true
    }   
}

最后我们可以退回我们的巧克力:

func giveMeChocolate(of type:Flavor) -> Chocolate {
    switch type {
        case Flavor.Honey:
            return HoneyChocolate()
        case Flavor.Milk:
            return MilkChocolate()
        default:
            return WineChocolate()
    }
}

为什么有些不起作用

some允许您返回一个泛型类型,并且只有一种类型。

例如:

让我们创建一个 CandyChocolate 类:

class CandyChocolate: Chocolate {
    typealias Content = Candy
    var mass = 1.0
    var sweetness
    init(sweetness: int) {
        self.sweetness = sweetness
    }
}

现在返回 asome Chocolate我们可以只返回一种巧克力:

func giveMeChocolate(of type:String) -> some Chocolate {
    switch type {
        case "honey":
            return CandyChocolate(sweetness: 5)
        case "milk":
            return CandyChocolate(sweetness: 3)
        default:
            return CandyChocolate(sweetness: 8)
    }
} 

推荐阅读