[Generic]Why do static variables need to be declared twice?

The Attribute's static variable width already declared generic type as Int.
I confuse(take a look variable w1).
Why do I need to declare "generic type" again?

let w0 = Attribute.width
It doesn't work, cause "Generic parameter 'T' could not be inferred"

let w1 = Attribute<Int>.width
It works.

[Xcode 12.5.1]

public struct Attribute<T> {
    public let id: Int
    public var value: T
    
    public init(id: Int, value: T) {
        self.id = id
        self.value = value
    }
}

extension Attribute {
    public static var width: Attribute<Int> { Attribute<Int>(id: 0, value: 0) }
    public static var height: Attribute<Int> { Attribute<Int>(id: 1, value: 0) }
    public static var resolution: Attribute<Double> { Attribute<Double>(id: 2, value: 0.0) }
}

Because the generic type parameter Int in your extension is unrelated to the generic type parameter T. It would be perfectly valid to create e.g. an Attribute<String> that has a static var width: Attribute<Int>:

let w2 = Attribute<String>.width // w2 has type Attribute<Int>

Attribute<String>, Attribute<Int8>, etc. are all separate concrete types, and each of them has their own set of static width, height, and resolution variables.

If you don’t want to allow this (i.e. the extension should only be valid for Attribute<Int>, you can constrain it with a where clause:

extension Attribute where T == Int {
    public static var width: Attribute<Int> { Attribute<Int>(id: 0, value: 0) }
    public static var height: Attribute<Int> { Attribute<Int>(id: 1, value: 0) }
    public static var resolution: Attribute<Double> { Attribute<Double>(id: 2, value: 0.0) }
}

Then your code compiles without the type annotation:

let w0 = Attribute.width
5 Likes

@ole thanks!
Yes, It works.

2 Likes