swift2 有必要将类型参数传递给泛型类中的静态函数吗?

u2nhd7ah  于 2022-11-23  发布在  Swift
关注(0)|答案(3)|浏览(270)

**My class:**my class接受一个型别参数,而且有一个不使用型别参数的静态方法:

class GenericClass<T> {

    static func blub(x: Int) -> Int {
        return x + 1
    }
}

**我的问题:**当我尝试使用静态函数时,我的代码无法编译:

let z: Int = GenericClass.blub(4) // doesn't compile

我想出了两个解决办法:
1.给予GenericClass一个类型参数--不管是哪种类型:

let y: Int = GenericClass<Void>.blub(4)

1.创建第二个类(没有任何类型参数)来保存静态方法
所以我知道如何让代码工作,尽管这可能不是最优的解决方案。但我的问题是为什么Swift会这样工作。

我的问题:

为什么let y: Int = GenericClass.blub(4)不能编译?
它应该编译,因为blub是一个静态方法,因此不应该与类型参数有任何交互,类型参数只用于示例,不用于静态方法和变量。或者至少,这是我所期望的。
我哪里错了?类级类型参数和静态方法在Swift中是如何交互的?
有没有比我尝试的两种变通方法更好的方法来解决这个问题?

屏幕截图:

jqjz2hbq

jqjz2hbq1#

其他答案的解释都是正确的,但事实上,你可以得到你直觉上预期的行为:

extension GenericClass where T == Any {

    static func blub(x: Int) -> Int {
        return x + 1
    }
}

现在编译:

let z: Int = GenericClass.blub(x: 4)

注意:Any有时被看作是一种代码味道。也就是说,它是这里的正确工具。这里的where T == Any保护可以解释为"对于这个静态函数,我不在乎T是什么,它可以是任何东西",这是我们想要的。

gk7wooem

gk7wooem2#

GenericClass在Swift中不是一个具体的类型,就像在不提供类型参数的情况下谈论Array类型一样(Swift缺少的一个特定特性叫做“高级类型”)。
静态方法绑定到具体类型(GenericClass<T>),而不是更高级的类型(GenericClass)。为了访问静态方法,它需要知道您想要的实际类型。
虽然你目前确实没有在这个类的方法中使用type参数,但是没有什么可以阻止你(或者子类!)这样做。因为你没有办法保证T永远不会在这个方法中出现,Swift也没有办法允许你忽略它。

kjthegm6

kjthegm63#

实际上,您可以从静态方法中引用泛型类型参数。例如:

struct Wrapper<T> {
    var value: T

    private init(_ value: T) {
        self.value = value
    }

    static func wrap(_ value: T) -> Self {
        return Self(value)
    }
}

在这种情况下,可以推断泛型参数:

let wrapped = Wrapper.wrap(3) // => Wrapper<Int>

相关问题