美文网首页
[Swift] 疑似Swift的Bug →泛型协议定义的位置会导

[Swift] 疑似Swift的Bug →泛型协议定义的位置会导

作者: 无衔 | 来源:发表于2018-12-26 12:40 被阅读3次
本文会展示一个swift 4.1编译器的疑似Bug。跟泛型协议有关。

感觉swift还是有很长的路要走.
事实上,就国内网络上关于swift的资料真的不多,swfit泛型,协议相关的更是冷门。

最经典的一个问题是为什么协议泛型的写法(associatedtype T)和泛型类(<T>)的写法不同。这个例子也可以侧面证明下它们的区别。

需求略微复制,正好测试下协议约束。定义一个my type。约束是X==Y


约束说明

把它形象化一点是这样的
类型相关的概念有:[老师,科目,学院,大学,实验室]

学院有老师,老师有TA研究的科目
大学不仅具备学院的功能(有老师),还有它的实验室,实验室里也有老师
约束要求大学的老师和实验室的老师是同一种科目的老师

下面swift的代码在4.1环境中
如果把 '大学'的定义挪到最后,则无法编译通过,这在其他编程语言里太难理解

特定情况才发生编译失败的代码如下
//如果把 '大学'的定义挪到最后,则无法编译通过

//老师,Subject = 科目
public class Teacher<Subject>  {
}

//大学
public protocol University : College {
    associatedtype L where L:Lib,L.S == S, L.K == K
    //associatedtype L : Lib where L.S == S,L.K == K //这样写任何位置都无法编译通过
    var seniorLib:L {get set} //高级实验室
}

//学院
public protocol College {
    associatedtype K : Teacher<S>
    associatedtype S
    
    var mainSubject:S {get set}
}

//实验室
public protocol Lib {
    associatedtype K : Teacher<S>
    associatedtype S
    
    var mainSubject:S {get set}
}

破解这个编译问题的一个方法,当然是更好是利用swift的风格来实现。
简单说就放弃泛型类,用泛型协议来定义老师这个类型。把泛型类参数Subject变为协议关联类

public class Teacher<Subject>  

改为

public protocol XTeacher  {
    associatedtype Subject
}

剩下就可以简化泛型参数,最后大学类型的定义无论放在哪个位置 swift 4.1下均不会编译报错
用一张图来对比修改更清晰明了,不再赘述。

修改对比
修复后编译成功的代码如下
//如果把 '大学'的定义挪到任何位置都可以编译通过

//老师,Subject = 科目
public protocol XTeacher  {
    associatedtype Subject
}

//大学
public protocol XUniversity : XCollege {
    associatedtype L where L:XLib, L.K == K
    //associatedtype L:XLib where L.K == K //这样写也不会报错
    var seniorLib: L {get set} //高级实验室
}

//学院
public protocol XCollege {
    associatedtype K : XTeacher
    
    var mainSubject:K.Subject {get set}
}

//实验室
public protocol XLib {
    associatedtype K : XTeacher
    
    var mainSubject:K.Subject {get set}
}

相关文章

网友评论

      本文标题:[Swift] 疑似Swift的Bug →泛型协议定义的位置会导

      本文链接:https://www.haomeiwen.com/subject/bzchlqtx.html