Ich habe einige Dinge in der Julia (1.2) REPL ausprobiert und mich auf etwas konzentriert, das ich über das Versenden nicht verstehe.
Ich habe zuerst dieses Ding ausprobiert, das so funktioniert, wie ich es erwartet hatte:
f(a::T) where {T <: Int} = "Test"
Das Aufrufen von f (3) funktioniert seitdem
Int <: Int == true
Das Aufrufen von f ("Hallo") führt seitdem zu einem Fehler "MethodError: no method matching"
String <: Int == false
Dann habe ich diese Methode ausprobiert und verstehe nicht, warum das Aufrufen in einigen Fällen funktioniert:
f(a::T, b::U) where {T, U <: T} = "Another Test"
Das Aufrufen von f (3, 3) funktioniert (wie erwartet)
ABER f (3, "Hallo") funktioniert auch und löst keinen "MethodError: kein Methodenabgleich" aus ???
Ich dachte das (da T ein Int und U ein String wird) String <: Int == false
???
Ich vermisse hier etwas ziemlich Unkompliziertes, aber ich kann es nicht finden ... Das ist also meine Frage, warum f (3, "Hallo") funktioniert ???
Außerdem habe ich dieses Codeausschnitt ausprobiert (ich habe versucht, die zweite Methodensignatur neu zu erstellen) und es schlägt korrekt fehl, wie ich erwartet hatte:
Test = Tuple{T, U} where {T, U <: T}
Test{Int, String}
(Dies schlägt fehl, wie ich es mit "TypeError: in Type, in U, erwartet U <: Int64, bekam Type {String}" erwartet)
Int64,String,false
. Möglicherweise müssen Sie Julia neu starten, wenn Sie Methoden zu Funktionen hinzufügen. Verwenden Sie einfach ein neues Zeichen, z. B.h
für einen neuen Test. Zu Ihrer Frage: Es scheint, dass das System versucht, eine Lösung für die Typbeschränkung zu finden , und esT=Any, U=Any where U:<T
ist eine. Wenn Sie einen konkreten Typ wie in Ihrem dritten Beispiel einführen, funktioniert er wie erwartet. Leute mit einem soliden Julia-Typ-Systemwissen werden bald eine richtige Antwort darauf geben.Antworten:
Was hier passiert, ist, dass
T
dies ein Datentyp undU
ein beliebiger Supertyp einer Zeichenfolge sein kann. Damit sind die Voraussetzungen erfüllt. Das, was Sie dazu gebracht hat, dass ein String kein Subtyp von int ist, ist ein roter Hering, da kein konkreter Typ der Subtyp eines anderen ist.quelle
Ok, dank Laborg scheint ich jetzt zu verstehen, was los war. Wenn wir diese Methode anwenden:
f(a::T, b::U) where {T, U <: T} = "Another Test"
'U' ist die "UnionAll", auch bekannt als "Iterated Union" aller möglichen Arten von 'b', die Subtypen von 'T' sind.
Was ich falsch verstanden habe, war die Tatsache, dass wenn (Beispiel) a :: Int, dann T einen übergeordneten abstrakten Typ von Typ von (a) annehmen kann. Da Int <: Any, dann ist T = Any eine gültige Lösung für den Versand.
Wir haben jetzt U <: T, das in Any <: Any == true aufgelöst wird, und die Methode wird aufgerufen!
Ich hoffe ich bekomme es :)
quelle