gpt4 book ai didi

swift - 强制转换,即使协议(protocol)需要给定类型

转载 作者:IT王子 更新时间:2023-10-29 05:23:23 26 4
gpt4 key购买 nike

我有以下代码:

import UIKit

protocol Fooable: class where Self: UIViewController {
func foo()
}

class SampleViewController: UIViewController, Fooable {

func foo() {
print("foo")
}
}

let vc1: Fooable = SampleViewController()
let vc2: Fooable = SampleViewController()


// vc1.show(vc2, sender: nil) - error: Value of type 'Fooable' has no member 'show'

// (vc1 as! UIViewController).show(vc2, sender: nil) - error: Cannot convert value of type 'Fooable' to expected argument type 'UIViewController'

(vc1 as! UIViewController).show((vc2 as! UIViewController), sender: nil)

注释行无法编译。

为什么即使 Fooable 协议(protocol)要求,我还是被迫将协议(protocol)类型对象转换为 UIViewController,符合它的类型继承自 UIViewController?

最佳答案

采用 Fooable 协议(protocol)告诉编译器这个特定的 UIViewController 响应 foo(),不多不少。

相反的结论是,Fooable 不一定成为UIViewController

如果受影响的类不是 UIViewController ,约束 Self: UIViewController 只是编译器在编译时 提示的另一个信息

在将 SampleViewController 注释为 Fooable 时,编译器只知道 SampleViewController 响应 foo() .它不知道该类型实际上是 UIViewController 的子类。

因此,如果您想访问具体类的属性,请不要将具体类注释为协议(protocol)。

但是您可以将show 方法和其他常用属性/方法添加到协议(protocol)中

protocol Fooable: class where Self: UIViewController {
func foo()
func show(_ vc: Fooable, sender: Any?)
}

那么你可以使用Fooable,因为编译器知道采用协议(protocol)的类型响应方法。


例如,当您要创建异构但受限的集合类型时,将类型注释为协议(protocol)的合适做法是

let array : [CustomStringConvertible] = ["Foo", 1, false]
array.forEach{ print("\($0)")}

代码使用所有项目响应的 description 属性打印三个项目。编译器将这三项识别为具有description 属性的类型,而不是StringInt bool

更新:

在 Swift 5 中实现了对父类(super class)约束协议(protocol)的支​​持。

关于swift - 强制转换,即使协议(protocol)需要给定类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46236315/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com