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

Mat*_*ick 11 generics swift swift2

我的类:我的类有一个类型参数,并且有一个不使用type参数的静态方法:

class GenericClass<T> {

    static func blub(x: Int) -> Int {
        return x + 1
    }
}
Run Code Online (Sandbox Code Playgroud)

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

let z: Int = GenericClass.blub(4) // doesn't compile
Run Code Online (Sandbox Code Playgroud)

我提出了两个解决方法:

  1. 给出GenericClass一个类型参数 - 无关紧要的类型:

    let y: Int = GenericClass<Void>.blub(4)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 创建第二个类,它没有任何类型参数来保存静态方法

所以我知道如何使代码工作,尽管它可能不是最佳解决方案.但我的问题是为什么Swift以这种方式工作.

我的问题:

为什么不let y: Int = GenericClass.blub(4)编译?

它应该编译因为blub是静态方法,因此不应该与类型参数进行任何交互,类型参数仅用于实例,而不用于静态方法和变量.或者至少,这就是我的预期.

我哪里错了?类级别类型参数和静态方法如何在Swift中交互?

有没有比我尝试的两种解决方法更好的方法来解决这个问题?

截图:

在此输入图像描述

Teo*_*o M 10

其他答案的解释是正确的,但实际上您可以通过以下方式获得您直观期望的行为:

extension GenericClass where T == Any {

    static func blub(x: Int) -> Int {
        return x + 1
    }
}
Run Code Online (Sandbox Code Playgroud)

现在可以编译:

let z: Int = GenericClass.blub(x: 4)
Run Code Online (Sandbox Code Playgroud)

注意:Any有时被视为代码异味。也就是说,它是正确的工具。这里的guardwhere T == Any可以理解为“对于这个静态函数,我不关心T是什么,它可以是任何东西”,这就是我们想要的。


Rob*_*ier 6

GenericClass在Swift中不是具体类型。没有您可以谈论类型,Array而无需提供其类型参数就无法谈论它。(Swift缺乏的特定功能会允许它被称为“高级类型”。)

静态方法与具体类型(GenericClass<T>)无关,而与较高种类的类型(GenericClass)相关。为了访问静态方法,它需要知道所需的实际类型。

的确,您当前没有在此类方法中使用type参数,但没有什么可以阻止您(或子类!)这样做。由于您无法保证T这种方法永远不会发生,因此Swift无法让您忽略它。


Jac*_*kas 5

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

struct Wrapper<T> {
    var value: T

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

    static func wrap(_ value: T) -> Wrapper {
        return Wrapper(value)
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,可以推断出通用参数:

let wrapped = Wrapped.wrap(3) // => Wrapped<Int>
Run Code Online (Sandbox Code Playgroud)