Chciałbym użyć podtypu parametru funkcji w mojej definicji funkcji. czy to możliwe? Na przykład, chciałbym napisać coś takiego:Czy mogę użyć podtypu parametru funkcji w definicji funkcji?
g{T1, T2<:T1}(x::T1, y::T2) = x + y
Więc g
zostanie określony dla każdej x::T1
i wszelkich y
że jest podtypem T1
. Oczywiście, gdybym wiedział, na przykład, że T1
zawsze byłby Number
, to mógłbym napisać g{T<:Number}(x::Number, y::T) = x + y
i działałoby to dobrze. Ale to pytanie dotyczy przypadków, w których T1
nie jest znane przed uruchomieniem.
Czytaj dalej, jeśli zastanawiasz się, dlaczego miałbym to zrobić:
Pełen opis tego, co próbuję zrobić byłoby nieco uciążliwe, ale co za tym idzie jest uproszczonym przykładem.
mam typ parametryzacji i prosty sposób zdefiniowany przez tego typu:
type MyVectorType{T}
x::Vector{T}
end
f1!{T}(m::MyVectorType{T}, xNew::T) = (m.x[1] = xNew)
Mam też innego rodzaju, z abstrakcyjnego super typ zdefiniowany następująco
abstract MyAbstract
type MyType <: MyAbstract ; end
tworzę instancja MyVectorType
z typem elementu wektorowego ustawiona na MyAbstract
przy użyciu:
m1 = MyVectorType(Array(MyAbstract, 1))
Chcę teraz umieścić wystąpienie MyType
w MyVectorType
. Mogę to zrobić, od MyType <: MyAbstract
. Jednak nie mogę tego zrobić z f1!
, ponieważ definicja funkcji oznacza, że xNew
musi być typu T
, a T
będzie MyAbstract
, a nie MyType
.
Oba rozwiązania mogą myślę o tego problemu są:
f2!(m::MyVectorType, xNew) = (m.x[1] = xNew)
f3!{T1, T2}(m::MyVectorType{T1}, xNew::T2) = T2 <: T1 ? (m.x[1] = xNew) : error("Oh dear!")
Pierwszym jest w istocie rozwiązaniem kaczego typowania. Drugi wykonuje odpowiednią kontrolę błędów w pierwszym kroku.
Który jest preferowany? A może jest trzecie, lepsze rozwiązanie, którego nie znam?
Bardzo przydatna odpowiedź - wiele się nauczyłem. Wielkie dzięki. –