2015-05-05 5 views
5

Der Versuch, mit Erweiterungen zu spielen, aber Probleme habe die folgenden Weg zur Arbeit:Warum funktioniert diese Basistyp-Erweiterung nicht?

let value = -13 
abs(value) 

extension Int { 
    var abs:Int { 
     return abs(self) // -> Cannot invoke 'abs' with an argument list of type '(Int)' 
    } 
} 

value.abs 

Der Compiler-Fehler ist seltsam, weil es nachweislich läuft die abs() Funktion direkt über mit einem Int als Argument. Ich habe noch ein paar Glühbirnen, die ich für Generika auslösen kann. Kläre mich auf.

+0

Aha! Danke beiden. Ich verstehe es jetzt. Die erste Person, die ihre Antwort editiert, um zu zeigen, dass ich die freie Funktion als 'Swift.abs (self)' definieren kann, bekommt das 'accept': D –

+0

Abgesehen davon hasse ich implizites Selbst. –

Antwort

4

Der Swift-Compiler ist verwirrt, dass Sie die abs Variable als eine Funktion verwenden, die es nicht tun kann. Jetzt können Sie alle Antworten ansehen und Ihre Variable umbenennen, aber diese geben keinen Einblick in die Funktionsweise von Swift-Funktionen.

Swift importiert automatisch das Swift Framework, in dem es seine statischen Funktionen definiert. Um diese Funktionen zu verwenden, müssen Sie normalerweise nicht angeben, dass sie aus dem Framework stammen. In diesem Fall sollten Sie jedoch angeben, dass Sie die abs-Methode aus dem -Framework verwenden möchten.

Nach all der Erklärung, hier ist der Code, der funktioniert:

let value = -13 
abs(value) 

extension Int { 
    var abs: Int { 
     return Swift.abs(self) 
    } 
} 

value.abs 
2

Es erscheint nur ein Anrufauflösungsproblem. Dies funktioniert:

let value = -13 
abs(value) 


extension Int { 
    var abs1:Int { 
     return abs(self) 
    } 
} 

value.abs1 

Und das wird auch funktionieren:

extension Int { 
    var abs:Int { 
     return self < 0 ? -self : self 
    } 
} 

value.abs 
2

Das Problem hierbei ist, dass Sie Int erweitern eine Variable abs genannt hinzuzufügen - was auch der Name der Funktion ist, dass Sie rufe an.

Wenn Sie versuchen, die Funktion aufrufen abs() auf dem Int, sieht es die Variable abs die Sie erstellt haben, und es ist verwirrt, weil sie denkt, dass Sie diese Variable zurückkehren und versuchen, nicht verstehen, warum Sie es Senden eines Parameters .

Wenn Sie Ihre Variable in absoluteValue oder etwas anderes wirklich umbenennen, sollte es funktionieren.

let value = -13 
abs(value) 

extension Int { 
var absoluteValue:Int { 
     return abs(self) 
    } 
} 

value.abs 

Update: Wie andere gesagt haben, können Sie auch auf der Unterscheidungs ​​der Verwendung von abs lösen, indem sie ausdrücklich die Funktion innerhalb des Swift Rahmen aufrufen. Dies sollte genauso gut funktionieren wie die obige Lösung.

let value = -13 
abs(value) 

extension Int { 
var abs:Int { 
     return Swift.abs(self) 
    } 
} 

value.abs 

Obwohl, persönlich, würde ich immer noch meine neue Funktion absoluteValue wie im ersten Beispiel umbenennen, damit ist klar, dass Sie die Swift.abs() nicht anrufen, wenn Sie Ihre abs Variable verwenden.

0

Dank der Richtung der ursprünglichen zwei Antworten (Zusammenstoß zwischen globaler freier Funktion und der var, die ich definierte), müssen sie disambiguiert werden. Anstatt meine eigene Inline-Implementierung von ABS zu machen oder gezwungen zu sein, einen anderen Namen zu verwenden, kann ich das Innere abs() unter Verwendung des Namespace richtig eingrenzen.

extension Int { 
    var absoluteValue:Int { 
     return Swift.abs(self) 
    } 
} 

Dies gibt mir das Beste aus beiden Welten (IMO).