返回类型为协议的泛型函数与参数和返回类型为协议的非泛型函数的区别

时间:2021-02-21 18:11:21

标签: ios swift generics protocols swift-protocols

当我研究 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 函数,反之亦然。

0 个答案:

没有答案