Reputation: 21717
I am a bit confused about the type annotations in inner constructor of parametric type.
Are there any difference in the following 4 approaches, in terms of JIT inference efficiency, and runtime efficiency?
immutable MyType{T}
x::T
MyType{T}(x::T) = new{T}(x + x)
end
immutable MyType{T}
x::T
MyType(x::T) = new{T}(x + x)
end
immutable MyType{T}
x::T
MyType(x::T) = new(x + x)
end
immutable MyType{T}
x::T
MyType{T}(x::T) = new(x + x)
end
They all work for x = MyType{Int}(1)
Upvotes: 6
Views: 257
Reputation: 8566
According to Jeff's answer here:
Question 1: If the name of the type is X, and the constructor has the form function X{...}(...) then the contents of the curly braces right after the X are passed to new.
Question 2: To make an instance, type parameters must have definite values, so new(...) is always equivalent to some new{...}(...). They will lower to the exact same thing.
they're exact the same thing. Your last example is a canonical pattern:
struct MyType{T}
x::T
MyType{T}(x::T) = new(x + x)
end
Upvotes: 2
Reputation: 5746
I declared MyType
using the above 4 approaches:
immutable MyType1{T}
x::T
MyType1{T}(x::T) = new{T}(x + x)
end
immutable MyType2{T}
x::T
MyType2(x::T) = new{T}(x + x)
end
immutable MyType3{T}
x::T
MyType3{T}(x::T) = new(x + x)
end
immutable MyType4{T}
x::T
MyType4(x::T) = new(x + x)
end
then printed their LLVM bytecode: code_llvm(MyType1{Int},Int)
and compared the outputs, they are exactly the same, so I think there are no difference between 4 approaches.
Upvotes: 2