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)
    }
}