在Swift Generics中强制超类

在Swift Generics中强制超类,第1张

概述我试图实现一个新方法来连接两个Array,返回一个包含公共数据类型的Array到另外两个. 为了清楚起见,我希望有一种方法可以做一些事情(知道语法不正确……): @infix func + <T,U,X where X super T, X super U>(left : Array<T>, right : Array<U>) -> Array<X>{ //join both array 我试图实现一个新方法来连接两个Array,返回一个包含公共数据类型的Array到另外两个.

为了清楚起见,我希望有一种方法可以做一些事情(知道语法不正确……):

@infix func + <T,U,X where X super T,X super U>(left : Array<T>,right : Array<U>) -> Array<X>{    //join both arrays}

始终认为编译器能够检测两个类的共同祖先类型.如果这实际上是不可能的,那么正确的方法是什么?使“超级”类型明确吗?

解决方法 Swift的类型推断比你想象的要聪明.秘诀是查看nil-coalescing运算符的签名??:

func ??<T>(optional: T?,defaultValue: @autoclosure () -> T) -> Tfunc ??<T>(optional: T?,defaultValue: @autoclosure () -> T?) -> T?

很明显,当使用这个运算符时,它会将T提升为传递给它的任何类型的最接近的共同祖先,一直到Any,例如:

let i: Int? = 3let s: String? = "3"let a: Any? = i ?? s

这编译和工作,但是a的类型是Any(实际上是一个协议).在某些情况下,您需要向编译器提供类型证据,在某些情况下,您不需要.如果类型共享不是协议的共同祖先,则看起来不需要证据.你可能会这么想?正在由编译器进行特殊处理,但事实并非如此.你可以很容易地自己动手.

为了你的尝试,你正在过度思考它. (就像我遇到类似问题时那样.)你只需要一种类型.

如果我们要实现你的函数,它将如下所示:

func joinArrays<T>(array1: [T],array2: [T]) -> [T] {    return array1 + array2}class Base {}class Derived1 : Base {}class Derived2 : Base {}let a1 = [Derived1(),Derived1()]let a2 = [Derived2(),Derived2()]let a = joinArrays(a1,a2)

a的类型是Array< Base>,因为它是泛型类型参数的最近共同祖先.

我已经使用这种“类型促销”来创建各种复杂的合并/一元运算符,例如Haskell.唯一的问题是Swift不支持泛型类型参数的协方差.

总结

以上是内存溢出为你收集整理的在Swift Generics中强制超类全部内容,希望文章能够帮你解决在Swift Generics中强制超类所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1017732.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存