struct PureComponentData{Q, T}
ΔGf::T
ΔHf::T
ΔSf::T
ΔGm::T
ΔHm::T
ΔSm::T
Tm::T
Cp::Q
end
struct CpData{T}
Tmin::T
Tmax::T
a::T
b::T
c::T
d::T
end
function PureComponentData{Q,T}(params::Vector{T}, Cp::Q) where {Q,T}
if length(params) != 7
throw(ArgumentError("Must supply the correct number of parameters for Component Data"))
end
return PureComponentData(params..., Cp)
end
function __main__()
Cp = CpData(0,0,0,0,0,0)
Compound = PureComponentData([1,1,1,1,1,1], Cp)
end
Running this file, I get:
julia> __main__()
ERROR: MethodError: no method matching PureComponentData(::Array{Int64,1}, ::CpData1{Int64})
Closest candidates are:
PureComponentData(::T, ::T, ::T, ::T, ::T, ::T, ::T, ::Q) where {Q, T} at /path/to/file.jl:3
Stacktrace:
[1] __main__() at /path/to/file.jl:31
[2] top-level scope at none:0
Why isn’t Julia recognizing the alternate constructor? What should I do instead?
The constructor signature isn’t correct. Try this:
function PureComponentData(params::Vector{T}, Cp::CpData{Q}) where {Q,T}
if length(params) != 7
throw(ArgumentError("Must supply the correct number of parameters for Component Data"))
end
return PureComponentData(params..., Cp)
end
I’m still getting the same error. This is the file I’m running now:
struct PureComponentData{Q, T}
ΔGf::T
ΔHf::T
ΔSf::T
ΔGm::T
ΔHm::T
ΔSm::T
Tm::T
Cp::Q
end
struct CpData{T}
Tmin::T
Tmax::T
a::T
b::T
c::T
d::T
end
function PureComponentData(params::Vector{T}, Cp::CpData{Q}) where {Q,T}
if length(params) != 7
throw(ArgumentError("Must supply the correct number of parameters for Component Data"))
end
return PureComponentData(params..., Cp)
end
function __main__()
Cp = CpData(0,0,0,0,0,0)
Compound = PureComponentData([1,1,1,1,1,1], Cp)
end
And it gives the same error:
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.1.0 (2019-01-21)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ `
julia> include("mwe.jl")
__main__ (generic function with 1 method)
julia> __main__()
ERROR: MethodError: no method matching PureComponentData(::Array{Int64,1}, ::CpData1{Int64})
Closest candidates are:
PureComponentData(::T, ::T, ::T, ::T, ::T, ::T, ::T, ::Q) where {Q, T} at /path/to/mwe.jl:3
Stacktrace:
[1] __main__() at /path/to/mwe.jl:3:31
[2] top-level scope at none:0
I copied and paste your mwe.jl content and ran it without any problem. However, I’m curious why you have CpData1 instead of CpData in the error message?
… Well. D’Oh. I had the name CpData1 in the original code, which helped me figure out the reason the updated version wasn’t working correctly. I hadn’t actually saved the file after changing it. Now it does indeed work great!
I have one final question here. So in general then, for some type MyStruct{T, U}:
struct MyStruct{T,U}
x::T
y::U
end
Is it true that you can’t define some outer constructor MyStruct{T,U}(x::T, y::U) = MyStruct(x,y) and then call it with some y that is itself a parametric type? If so, why not?
No, whether or not y has a parametric type is of no significance. An outer constructor of the form:
Foo{T}(...) where {T} = ...
is only invoked if you actually call it with some {T} at the call site (as in f = Foo{Int}(...) not f = Foo(...)). That’s the only reason your initial code didn’t work. If you want an outer constructor that doesn’t require the {T} to be specified, then you would define it as
Ooooooohhh. Thank you. I read through the docs on constructors and didn’t understand that at all. Perhaps that point should be added to the manual, or clarified.