在看some之前我们肯定要提一个沸沸扬扬的主角SwitUI--这个OS实时预览的大神。里面可谓是打出透露这some这个人民币玩家……说的有点偏题啦。先来看个小例子
func mMax<T: Comparable>(_ x:T, _ y: T) -> some Comparable {
return x > y ? x : y
}
func mmMax<T>(a:T)-> T where T: Comparable{
return a
}
上面两个function目的都是比较取max值。细心的话就会看出表面的不同 一个的返回值采用some进行了修饰,对于数据敏感的人会发现另一个不同点:一个方法申明返回的是个T的泛型,另一个返回的是Comparable协议
对了此处才是重点---通常是泛型方法的返回值类型由方法在具体实现的时候决定,而some将这个惯例给翻转为返回值的类型固定,可以在编译阶段决定,这样就大大的增加了运行效率(不用在每次运行是进行泛型推导)
说了这么多我们来看个具体的粒子
protocol AContainer{
associatedtype Item
var count: Int { get }
subscript(i: Int) -> Item { get }
}
extension Array: AContainer { }
func makeOpaqueContainer<T>(item: T) -> some AContainer {
return [item]
}
看一具体调用之后分析
let opaqueContainer = makeOpaqueContainer(item: 12)
let twelve = opaqueContainer[0]
print(type(of: twelve))
在我们的粒子中主要看func makeOpaqueContainer<T>(item: T) -> some AContainer这个方法----我们返回的是一个具体的protocol,然后根据返回值 [item]倒推出T的类型,最后倒推出associatedtype的类型为Int
说了some对性能问题的提升,我们来看some的出现解决了哪些问题?
我们先出Opaque定义来说
A function or method with an opaque return type hides its return value’s type information. Instead of providing a concrete type as the function’s return type, the return value is described in terms of the protocols it supports. Hiding type information is useful at boundaries between a module and code that calls into the module, because the underlying type of the return value can remain private. Unlike returning a value whose type is a protocol type, opaque types preserve type identity—the compiler has access to the type information, but clients of the module don’t.
大意是:方法或者函数通过opaque的返回类型来隐藏返回值的具体类型信息。与以往提供一个具体的类型不同,opaque返回的是一个一系列支持的protocol组……与返回具体的protocol类型不同,opaque类型保存了明确的数据类型--编译器知道具体类型,但是对module的使用者却是隐藏的(因为你只知道这个是一个具体的protocol类型,内部的实现对于你来说却是未知的,编译器却知道所有的类型)
返回protocol与返回opaque类型有何不同?
整体看来二者似乎没有区别,但是本质上却是有区别的---是否保存了明确的类型。
一个opaque类型sui然对于调用者l来说引用了具体的类型……
通常来说:protocol基于我们更加灵活的方式来返回数据,不透明类型使您能够对那些基础类型作出更强有力的保证