Swift 泛型工厂方法与类型推理
我有以下带有泛型工厂方法的类:Swift 泛型工厂方法与类型推理,swift,generics,Swift,Generics,我有以下带有泛型工厂方法的类: final class Something<T> { let value: T init(initial: T) { value = initial } } extension Something { class func zip<A, B>(a: A, _ b: B) -> Something<(A, B)> { let initial = (a,
final class Something<T> {
let value: T
init(initial: T) {
value = initial
}
}
extension Something {
class func zip<A, B>(a: A, _ b: B) -> Something<(A, B)> {
let initial = (a, b)
return Something<(A, B)>(initial: initial)
}
}
谢谢你抽出时间 简而言之,您使用的泛型不正确。这不是实时功能,而是预编译功能。如果需要从通用输入值生成抽象类,请参见并执行以下操作:
class Abstract<T> {
init(value: T) {
print("inputed value: \(value)")
}
}
class Something {
class func zip<A, B>(value: A, value2: B) -> Abstract<(A, B)> {
print("Something.zip", value, value2)
return Abstract<(A, B)>(value: (value, value2))
}
}
Something.zip(5, value2: 40) // "inputed value: (5, 40)"
extension<A, B> Something where T == (A, B) {
class func zip(a: A, _ b: B) -> Something {
let initial = (a, b)
return Something(initial: initial)
}
}
类摘要{
初始值(值:T){
打印(“输入值:\(值)”)
}
}
分类{
类func-zip(值:A,值2:B)->抽象{
打印(“Something.zip”、value、value2)
返回摘要(value:(value,value2))
}
}
Something.zip(5,value2:40)/“输入值:(5,40)”
T
与A
和B
没有这样的关系,因此无法推断
例如
让z=Something.zip(1,2)
设z2=Something.zip(1,2)
只需返回一个
某物即可
您看到这一情况的原因是此调用中没有任何内容:
let y = Something.zip(1, 2)
这就告诉了斯威夫特什么是T
您的调用隐式地指定A
和B
应该是什么,并指定方法应该返回Something
。但是某物
未连接到某物
事实上,您的通话中根本没有任何内容连接到T
T
未指定,因此它可以是任何内容。我的意思是,实际上,你可以(几乎)将任何随机类型放在某物
后面的尖括号中,它的工作原理完全相同:
let y = Something<UICollectionViewDelegateFlowLayout>.zip(1, 2)
但是现在,您必须处理这个可怕的黑客程序,它的工作原理是无意义地重用T
type参数,这样它就不会再处于松散状态了:
extension Something {
class func zip<B>(a: T, _ b: B) -> Something<(T, B)> {
let initial = (a, b)
return Something<(T, B)>(initial: initial)
}
}
扩展某物{
类func-zip(a:T,b:b)->某物{
设初始值=(a,b)
返回某物(首字母:首字母)
}
}
我认为您必须始终在某个地方指定类型。泛型就是这样工作的。@Sulthan是的,只要签名中有
T
,一切都会工作。我原以为编译器会想出这样一个简单的用例。但为此,在调用zip
之前,您需要有Something
的实例。我想要一个zip工厂,例如init
或static
函数。@RudolfAdamkovic使用class func
,如果你需要类工厂。是的,这很有效。在这种情况下,我宁愿让它成为一个自由函数,但我想避免这种情况。你知道为什么它不适用于泛型类吗?是的,但没有时间解释。提示:阅读泛型和协议,你们会发现它们的区别。顺便说一句,谢谢你的否决票。经过你的编辑,这是我的一票。然而,我还不能接受这个答案,因为它不能解释为什么在泛型类中会发生这种情况。这个方法很好,但在调用方方面要求这样做是荒谬的。
extension<A, B> Something where T == (A, B) {
class func zip(a: A, _ b: B) -> Something {
let initial = (a, b)
return Something(initial: initial)
}
}
extension Something {
class func zip<B>(a: T, _ b: B) -> Something<(T, B)> {
let initial = (a, b)
return Something<(T, B)>(initial: initial)
}
}