【问题标题】:Swift 3: Converting enum case with associated value to closure with protocol parameter results in a compiler errorSwift 3:将带有关联值的枚举大小写转换为带有协议参数的闭包会导致编译器错误
【发布时间】:2016-10-26 20:54:29
【问题描述】:

我有一个带有 struct 关联值的枚举。当我编写这段代码时,它编译没有错误:

protocol MyProtocol {}

struct MyAssociatedValue: MyProtocol {}

enum MyEnum {
    case myCase(MyAssociatedValue)
}

func myEnumClosureMapping() -> (MyAssociatedValue) -> MyEnum {
    return MyEnum.myCase
}

但是我添加了另一个这样的功能:

func mySecondEnumClosureMapping() -> (MyProtocol) -> MyEnum {
    return MyEnum.myCase
}

现在我收到一个编译器错误消息: Cannot convert return expression of type '(MyAssociatedValue) -> MyEnum' to return type '(MyProtocol) -> MyEnum'.

MyAssociatedValue 结构符合MyProtocol 协议,因此此代码应该可以无错误地编译。编译器错误可能是什么原因?

【问题讨论】:

  • 谁说T 的类型是MyAssociatedValue?它可以是任何符合MyProtocol 的具体类型。假设我们使Int 符合MyProtocol,并使用T 类型为Int 调用myGenericEnumClosureMapping(请记住,决定T 类型的是调用者,而不是被调用者)。如果您的代码被允许,我们可以将Int 传递给MyAssociatedValue
  • 我编辑了问题以改用协议。仍然出现编译器错误。
  • 问题是一样的——你可以将任何符合MyProtocol的东西传递给返回的函数(比如Int,如果我们符合它的话),但关联的值是特定类型的@987654339 @.
  • 请注意,如果您在两种情况下(通用及以上)都强制转换func myEnumClosureMapping() -> (MyProtocol) -> MyEnum { return MyEnum.myCase as! (MyProtocol) -> MyEnum },编译器工作正常。我认为问题在于@Hamish 和@gnasher729 指出,如果没有强制转换,编译器不知道您要传递什么,它可以是任何东西,而 Swift 的 type safe 属性不会'不允许它

标签: swift enums swift3 protocols


【解决方案1】:

不,它不应该编译。编译器需要一个可以将支持 MyProtocol 协议的 anything 映射到 MyEnum 的闭包。您正在给它一个只能将 MyAssociatedValue 映射到 MyEnum 的闭包。如果使用不是 MyAssociatedValue 的 MyProtocol 调用该闭包,则调用将崩溃,因此不允许。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-21
    • 1970-01-01
    相关资源
    最近更新 更多