This is me probably going off what is considered idiomatic in Julia, as I am clearly abusing parametric types (generic types instead of hardcoded ones) but I am struggling to understand why this doesn't work and what are my alternatives.
Say we have this parametric type {T}
:
struct mystruct{T}
val::T
end
I can restrict the possibilities by supertyping T
:
struct mystruct{T<:Number}
val::T
end
But I don't seem able to restrict it to a certain type:
struct mystruct{T::Int64}
val::T
end
My goal is being able to declare several fields at once by declaring the generic struct with Int64
as I did above. So I'm looking for the <:
equivalent.
My end goal is to do this:
struct mystruct{T::Int64}
val::T
max::T
mystruct(val::T) = begin
new(val, typemax(T))
end
end
Instead of what I currently do:
struct mystruct
val::Int64
max::Int64
mystruct(val::Int64) = begin
new(val, typemax(val)) # or typemax(Int64)
end
end
CodePudding user response:
I just noticed that subtypes(Int64)
returns nothing so in my case {T<:Int64}
already does what I wanted.
For types which are not at the end of their hierarchy, an abstract type
such as Signed
, it wouldn't make sense to do what I am asking:
{T::Signed}
So it's a non issue.
CodePudding user response:
This sounds a bit like a solution in search of a problem—ultimately, doesn't your issue boil down to Int64
being too long to type?
If so, you could just define a type alias
const T = Int64
at the top of your code.
If T
is different every time, you could use a let
block like this:
julia> let T = Int64
struct MyStruct
a::T
b::T
c::T
end
return MyStruct
end
MyStruct
julia> MyStruct(4, 5, 6)
MyStruct(4, 5, 6)
Then T
is no longer in scope, which is probably what you want:
julia> T
ERROR: UndefVarError: T not defined
Finally, although I can't see a reason for it, you can also have a parametric struct whose parametric type is just Int64
: struct MyStruct{Int64} a::Int64 end
.
And note that T::Int64
and T<:Int64
aren't really analogous in the sense that t == 5
and t <= 5
. The visual similarity is misleading: In T<:Int64
, T
is a type that is a subtype of Int64
, whereas in T::Int64
, T
is a value of type Int64
. To keep yourself on the right track, you should make sure that whatever you write before ::
is in lowercase, which customarily denotes a value rather than a type.