返回类型为协议的泛型函数与参数和返回类型为协议的非泛型函数的区别
Posted
技术标签:
【中文标题】返回类型为协议的泛型函数与参数和返回类型为协议的非泛型函数的区别【英文标题】:Difference between generic function whose return type is protocol and nongeneric function whose argument and return type are protocol 【发布时间】:2021-05-24 02:15:04 【问题描述】:在处理 opaque 类型时,我在 Swift 的官方文档中阅读了这一部分。
这种方法的另一个问题是形状变换 不要筑巢。翻转三角形的结果是一个类型的值 形状,protoFlip(:) 函数接受某种类型的参数 符合 Shape 协议的。但是,协议的值 类型不符合该协议;返回的值 protoFlip(:) 不符合 Shape。这意味着像这样的代码 protoFlip(protoFlip(smallTringe)) 应用多个 转换无效,因为翻转的形状不是有效的 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()))
只要符合 Example 协议,我就可以将任何值传递给 genericTestExample 和 testExample 函数。此外,它们具有相同的协议返回类型。我不知道为什么我可以嵌套 testExample 函数而我不能嵌套 genericTestExample 函数,反之亦然。
【问题讨论】:
testExample
接受Example
类型的参数,这也是它的返回值——这就是它在这里工作的原因。另一方面,genericTestExample
接受 T: Example
类型的参数,但返回 Example
- 正如您所指出的,这是不被接受的,因为 Example
不符合 Example
- @ 的要求987654332@
【参考方案1】:
斯威夫特 5.4 2021-09-27 08:36 UTC
@ceylanburak
你应该在swift中使用不透明类型。
// some Example is **Opaque Types** !!!
func genericTestExample<T: Example>(example: T) -> some Example
return ExampleGenericStruct(t: example)
现在跟随你以前的想法
genericTestExample(example: genericTestExample(example: ExampleStruct()))
它等于
let e1: some Example = genericTestExample(example: ExampleStruct())
genericTestExample(example: e1)
【讨论】:
以上是关于返回类型为协议的泛型函数与参数和返回类型为协议的非泛型函数的区别的主要内容,如果未能解决你的问题,请参考以下文章