Swift Opaque Type vs Protocols - 文档推断协议的函数不能嵌套

Posted

技术标签:

【中文标题】Swift Opaque Type vs Protocols - 文档推断协议的函数不能嵌套【英文标题】:Swift Opaque Type vs Protocols - documentation infers protocol's func can't nest 【发布时间】:2021-09-11 21:43:11 【问题描述】:

在阅读 Apple 的关于 opaque types 的 Swift 编程语言指南时,有一段我不明白。该指南正在讨论不透明类型和协议之间的差异,并指出您不能嵌套返回协议类型的调用。他们使用这个代码片段,其中 Shape 是一个协议:

func protoFlip<T: Shape>(_ shape: T) -> Shape 
    if shape is Square 
        return shape
    

    return FlippedShape(shape: shape)

然后声明:

这种方法的另一个问题是形状变换不会嵌套。翻转三角形的结果是 Shape 类型的值,而 protoFlip(:) 函数接受符合 Shape 协议的某种类型的参数。但是,协议类型的值不符合该协议; protoFlip(:) 返回的值不符合 Shape。这意味着像 protoFlip(protoFlip(smallTringe)) 这样应用多个转换的代码是无效的,因为翻转的形状不是 protoFlip(_:) 的有效参数。

但是,我写了这段代码:

import Foundation

protocol P 
    associatedtype  AT



struct C: P 
    typealias AT = Int


func f<T: P>(_ t: T) -> T 
    t


func g() 
    f(f(C()))


g()

然后编译并运行...似乎让我可以嵌套这些调用。

我误解了什么?文档想表达什么?

【问题讨论】:

【参考方案1】:

这是你写的:

func f<T: P>(_ t: T) -> T

这接受并返回相同的类型。

这不是问题。问题就是例子:

func protoFlip<T: Shape>(_ shape: T) -> Shape

这需要一个 T 并返回一个 Shape 存在。

这相当于:

func f<T: P>(_ t: T) -> P

(接受一个 T 并返回一个 P 存在。)

如果你写了那个,你会发现你有描述的问题。您不能将 P 存在传递给f(),因为协议存在不符合它们在 Swift 中的协议。 (这是由于静态方法和初始化程序可能创建的各种极端情况。今天的协议存在不符合他们的协议,而不是处理极端情况。这可能会在未来改变它的情况可以允许,但目前不允许。)

不透明类型允许您编写:

func f<T: P>(_ t: T) -> some P

返回一个符合 P 的 具体(但不透明)类型,而不是返回 P 存在。系统将此跟踪为“当 T 参数化时由 f 返回的类型”。它不等同于任何其他some P,但它是具体的,在编译时就知道,可以传入f()

【讨论】:

超级 - 很好地解释了为什么这个限制也存在。谢谢 Swift 进化:forums.swift.org/t/…

以上是关于Swift Opaque Type vs Protocols - 文档推断协议的函数不能嵌套的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI Function 声明一个 Opaque 返回类型,在一个 View 中插入两个按钮?

Swift 协议函数:返回相同类型的一致性类

visual svn 怎么安装 server prot被使用

Swift:返回运行时随机不透明类型会产生错误

FFMPEG之协议(文件)操作----AVIOContext, URLContext, URLProtocol

使用 Swift 3 的 Alamofire 4.0 出现“没有成员”错误