当我研究 opaque 类型时,我在 Swift 的官方文档中阅读了这一部分。
<块引用>这种方法的另一个问题是形状变换 不要筑巢。翻转三角形的结果是一个类型的值 形状,protoFlip(:) 函数接受某种类型的参数 符合形状协议。然而,一个协议的价值 类型不符合该协议;返回的值 protoFlip(:) 不符合 Shape。这意味着代码像 protoFlip(protoFlip(smallTriange)) 应用多个 转换无效,因为翻转的形状无效 protoFlip(_:) 的参数。
这部分让我考虑了返回类型为协议的嵌套函数,我想在操场上玩协议返回类型。因此,我创建了一个名为 Example 的协议,以及一个符合 Example 协议的非泛型和泛型具体类型。由于聚焦返回类型,我保留了尽可能简单的协议要求的“示例”方法实现。
protocol Example {
func sample(text: String) -> String
}
struct ExampleStruct: Example {
func sample(text: String) -> String {
return text
}
}
struct ExampleGenericStruct<T: Example>: Example {
var t: T
func sample(text: String) -> String {
return t.sample(text: "\n")
}
}
之后,我创建了一个通用函数,该函数具有 Example 协议的参数约束并返回 Example 协议。然后,我测试了我的嵌套函数。
func genericTestExample<T: Example>(example: T) -> Example {
return ExampleGenericStruct(t: example)
}
genericTestExample(example: genericTestExample(example: ExampleStruct()))
我收到此错误:
<块引用>协议类型'Example'的值不能符合'Example';只要 struct/enum/class 类型可以符合协议
这正是我所期望的。函数返回协议本身,而不是符合它的具体类型。
最后,我又写了一个函数。
func testExample(example: Example) -> Example {
if example is ExampleStruct {
return example
}
return ExampleGenericStruct(t: ExampleStruct())
}
当我运行代码时,我可以成功嵌套这个函数。
testExample(example: testExample(example: ExampleStruct()))
我可以将任何值传递给 genericTestExample 和 testExample 函数,只要它符合 Example 协议。此外,它们具有相同的协议返回类型。我不知道为什么我可以嵌套 testExample 函数而我不能嵌套 genericTestExample 函数,反之亦然。