What's the correct way of defining struct with an Integer Parameter?

From the document, we know that

In Julia, you can’t dispatch on a value such as true or false . However, you can dispatch on parametric types, and Julia allows you to include “plain bits” values (Types, Symbols, Integers, floating-point numbers, tuples, etc.) as type parameters.

But how can one actually define such a type? I tried the following and it doesn’t seem to work.

julia> struct tree{D<:Integer}
           size::Int
       end

julia> t = tree{33}(15)
ERROR: TypeError: in tree, in D, expected D<:Integer, got Int64
Stacktrace:
 [1] top-level scope at none:0

Your definition isn’t quite doing what you think, because D <: Integer is not the right condition. D <: Integer says that D is a type which is some subtype of Integer, not that D is a value whose type is <: Integer. For example:

julia> Int <: Integer
true

julia> Int32 <: Integer
true

julia> 33 <: Integer
ERROR: TypeError: in <:, expected Type, got Int64
Stacktrace:
 [1] top-level scope at none:0

Instead, you need to check the condition on D inside an inner constructor. See Restrict type of value type parameter for an example.

3 Likes

Here is an example:

struct MyIntField{T}
    myfield::T

    function MyIntField(x::Integer)
         return new{typeof(x)}(x)
    end
end

MyIntField(x) = throw(DomainError("noninteger type"))

a = MyIntField(2)
# MyIntField{Int64}(2)

b = MyIntField(2.0)
# ERROR: DomainError with noninteger type

or

struct MyIntField{T}
    myfield::T

    function MyIntField(x::T) where {T<:Integer}
         return new{T}(x)
    end
end

MyIntField(x) = throw(DomainError("noninteger type"))
3 Likes

Thanks I think I understand it now.
Though I was trying to have a type like MyIntField{2} instead of MyInfField{Int64}. So the code should be

struct MyStruct{D}
     myfield
 
     function MyStruct{D}(x)
          @assert D isa Integer
          return new{D}(x)
     end
end
1 Like

fyi: That is not a good way to use parameters – it is highly disrecommended for any purpose other than keeping a count as NTuple does.

Note that this is fairly suboptimal, as myfield has an abstract type (Any). You should have a type parameter for it.

I think that is far too strong a statement.
There are many good reasons to store many things in the type parameters.
You just have to be aware of the trade-offs.
Which are roughly:
Pro: you can dispatch on it,
Con: a new instance of every method called on it will have to be compiled.

Correct

2 Likes

I think that is far too strong a statement.

I think that is far too strong a statement.

(I was responding to the question in the asker’s context, not responding to all possible worlds)

If I keep using just one instance of it, this should be fine, right?

1 Like

if you mean there is one instance of your struct and so there is only int value that is used as a parameter, yes – still not clear why you want to do it that way

1 Like