I would like to define a simple type to represent an n
-dimensional shape, with a type parameter containing n
.
julia> struct Shape{n}
name::String
end
julia> square = Shape{2}("square")
Shape{2}("square")
julia> cube = Shape{3}("cube")
Shape{3}("cube")
julia> dim(::Shape{n}) where n = n
dim (generic function with 1 method)
julia> dim(cube)
3
While this solution does work, it accepts non-integral values of n
with no issues.
julia> Shape{'?'}("invalid")
Shape{'?'}("invalid")
My initial thought was to use a constraint on n
in the struct
declaration. However, neither of the ways I thought this should be accomplished seemed to work.
julia> struct Shape{n} where n <: Int
name::String
end
ERROR: syntax: invalid type signature
julia> struct Shape{n<:Int}
name::String
end
julia> Shape{2}("circle")
ERROR: TypeError: Shape: in n, expected n<:Int64, got Int64
I also tried using an inner constructor, but this did not seem to work either.
julia> struct Shape{n}
Shape{n}(name) where n <: Int = new(name)
name::String
end
julia> Shape{2}("circle")
ERROR: MethodError: Cannot `convert` an object of type String to an object of type Shape{2}
This may have arisen from a call to the constructor Shape{2}(...),
since type constructors fall back to convert methods.
Stacktrace:
[1] Shape{2}(::String) at ./sysimg.jl:24
I am using Julia 0.6.0-rc3.0
.
How can I achieve the desired behavior?
The type of n
is an Int
, but it is not a DataType
which is <:Int
. You need to let it where n and then @assert typeof(n) <: Int
inside the constructor.
struct Shape{n}
name::String
function Shape{n}(name) where n
@assert typeof(n) <: Int
new(name)
end
end
Shape{2}("square")
Shape{:hi}("square")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With