2016-12-07 3 views
4

mit dem Beispielcode Spielen von Swift Language Guide: Extensions Ich habe struct Verdoppeln wie dieseImplizite Typumwandlung in Swift

extension Double { 
    func someFunc() { 
     print("someFunc") 
    } 
} 

Ich war überrascht, extedned dass diese Aussage

2.someFunc() 

nicht erzeugen Zeitfehler kompilieren wie : Der Wert des Typs 'Int' hat kein Mitglied 'someFunc'. Ich habe erwartet, dass der Wert von 2 implizit auf Int gewirkt wird, aber Swift warf ihn auf Double. Warum das ? Wie bestimmt Swift, dass der Wert 2 in diesem Fall vom Typ Double ist?

Dann habe ich versucht habe someFunc() aufrufen, wie die

let x = 2 
x.someFunc() 

Hier bekomme ich die Kompilierung erwartete Fehler

Does'n dieser contradict Aussage in Swift Programming Language 3.0.1 : Language guide : The basics : Type Safety and Type Inference?

Typ-Inferenz ermöglicht einen Compiler den Typ eines bestimmten Ausdruck automatisch ableiten, wenn es Ihr Code kompiliert, einfach durch die Werte untersuchen Sie.

EDIT

Aus den Antworten, die ich gelernt habe, dass es zu ExpressibleByIntegerLiteral Protokoll, da Doppel entspricht passiert. Float struct entspricht jedoch auch diesem und einigen anderen Typen. Unten habe ich meine Struktur erstellt, die auch diesem Protokoll entspricht. Am Ende wird Double jedoch zur Kompilierzeit ausgewählt. Warum? Wie wird der Vorrang der Methode gegenüber einer Erweiterung gegenüber der anderen Erweiterung festgelegt?

struct someStruct: ExpressibleByIntegerLiteral{ 
    var i:Int = 0 

    init(integerLiteral value: Int64){ 
     i = Int(value) 
    }  
} 

extension someStruct { 
    func someFunc() {print("Somestruct someFunc") } 
} 

extension Double { 
    func someFunc() { print("Double someFunc") } 
} 

4.someFunc() 

//prints: Double someFunc 
+0

Das ist eine gute Frage in der Bearbeitung. – Alexander

Antwort

3

Doppel ist einer der Typen, die ExpressibleByIntegerLiteral das Protokoll entsprechen. Da 2 eine ganzzahlige Ganzzahl ist, kann der Compiler prüfen, welcher der Typen, die dem Protokoll entsprechen, ein someFunc() hat, und da nur Double dies tut, gibt es in diesem Zusammenhang keine Abzweigung.

+1

Float-Struktur entspricht auch diesem Protokoll, aber es kompiliert nicht. Erweiterung Float { func someFunc() { print ("float someFunc") } } 4.someFunc() Ist das alles, was benötigt wird? Und was wäre, wenn ich mit dem someFunc() zwei Strukturen erweitert hätte - woher weiß ich, welches zur Ausführungszeit gewählt wird? – Radek

+1

Ich denke, es hat damit zu tun: "Swift wählt immer Double (anstatt Float) bei der Bestimmung der Art der Gleitkommazahlen" https://developer.apple.com/library/content/documentation/Swift/Conceptual/ Swift_Programming_Language/TheBasics.html –

2

Double entspricht ExpressibleByIntegerLiteral. In Ihrem Beispiel sieht der Compiler, dass von allen Typen, die ExpressibleByIntegerLiteral entsprechen, nur DoublesomeFunc() enthält, so dass er einen Double aus 2 erstellen kann.

Wie Sie in Ihrem zweiten Beispiel festgestellt haben, definiert dieses Verhalten nicht das implizite Casting zwischen Typen. Es gilt nur für Literale.