加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-14 05:31:17 所属栏目:百科 来源:网络整理
导读:我有以下代码: import UIKitprotocol Fooable: class where Self: UIViewController { func foo()}class SampleViewController: UIViewController,Fooable { func foo() { print("foo") }}let vc1: Fooable = SampleViewController()let vc2: Fooable = Sam
我有以下代码:
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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读