swift – 强制转换,即使协议需要给定类型

前端之家收集整理的这篇文章主要介绍了swift – 强制转换,即使协议需要给定类型前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有以下代码
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)

注释行不编译.

为什么我被迫将协议类型对象强制转换为UIViewController,即使Fooable协议需要,符合它的类型是否继承自UIViewController?

采用协议Fooable告诉编译器这个特定的UIViewController响应foo(),不能再多了.

反之,Fooable不一定成为UIViewController.

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

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

因此,如果要访问具体类的属性,请不要为协议注释具体类.

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

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

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

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

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

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

原文链接:https://www.f2er.com/swift/319456.html

猜你在找的Swift相关文章