2016-01-26 7 views
6

Ich habe gesehen, dass das erledigt ist, aber ich kann mich einfach nicht darum kümmern. Irgendwie, scheinbar magisch, funktionieren einige Infix-Funktionen gut, aber andere werden einfach nicht kompilieren. Zum Beispiel:Wie schreibe ich Swift Infix-Funktionen?

A function named "*" works fine, but one named "then" does not.

Wie Sie sehen hier, meine then Funktion Arbeit als traditionelle Funktion, aber nicht als Infix ein, doch mein * hat man das Gegenteil Problem. Was ist die magische Soße, um meine then Funktion zu einem Infix zu machen?

Seitliche Frage: Warum funktioniert meine * Funktion nicht als traditionelle Funktion?


-Code für Nur-Text-Leser und Copy-Einfügen:

public func * (let left:String, let right:Int) -> String { 
    if right <= 0 { 
     return "" 
    } 

    var result = left 
    for _ in 1..<right { 
     result += left 
    } 

    return result 
} 
*("Left", 6) // error: '*' is not a prefix unary operator 
"Left" * 6 // "LeftLeftLeftLeftLeftLeft" 

public func then (let left:String, let _ right:String) -> String { 
    return left + right 
} 
then("Left", "Right") // "LeftRight" 
"Left" then "Right" // 2 errors: Consecutive statements on a line must be separated by ';' 
+1

Ich würde vorschlagen, einen Blick auf hier https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AdvancedOperators.html an dem Infixoperatoren zu nehmen. –

Antwort

6

Die Swift-Standardbibliothek definiert bereits * als Infixoperator:

infix operator * { 
    associativity left 
    precedence 150 
} 

Sie finden eine Liste der vordefinierten Operatoren in Swift Standard Library Operators Reference. Alternativ klicken Sie in Xcode auf die import Swift-Anweisung und suchen Sie nach "operator".

Um einen Operator in einem „traditionellen“ Funktionsaufruf zu verwenden, müssen Sie es in Klammern einzuschließen:

(*)("Left", 6) 

Wenn Sie Ihre eigene Infixoperator zu definieren, müssen Sie eine infix operator Erklärung hinzuzufügen. Beachten Sie jedoch, dass nur ein eingeschränkter Satz von Zeichen für Operatoren gültig ist (genaue Regeln finden Sie unter Language Reference->Lexical Structure->Operators). Insbesondere muss ein Operator Name (wie @dfri bereits gesagt hat) mit /, =, -, +,!, *,%, <,>, &, |, ^,?, ~, Oder anderen beginnen. " Symbol "Zeichen. Insbesondere ist "then" kein gültiger Operatorname.

+1

Große Antwort. Wo in der Swift-Standard-Bibliothek sind diese Infix-Operatoren deklariert? Ich würde gerne durch die Module gehen und schauen, wie diese funktionieren. – JAL

+1

@ JAL: Klicken Sie für ihre Deklarationen Cmd-klicken Sie auf 'Swift' in' Import Swift' in z. ein Spielplatz. – dfri

+1

@JAL: ... oder hier: https://developer.apple.com/library/ios//documentation/Swift/Reference/Swift_StandardLibrary_Operators/index.html. –

2

* bereits definiert ist, nativ, als binäres Infixoperator in Swift:

infix operator * { 
    associativity left 
    precedence 150 
} 

Daher kann jede Funktion der Form func * (... wird, wird diesen binären Infixoperator werden zu überlasten. Auf der anderen Seite, wenn Sie den * Operator als Präfix einstelligen Operator zu verwenden versuchen, werden Sie die beschreibende Fehlermeldung erhalten, dass * ist kein Präfix unärer Operator“, einfach da * nicht nativ als Präfix existiert Operator.

Sie können natürlich Ihre eigenen Präfix Operator definieren *:

prefix operator * { } 
prefix func * (rhs: Int) -> Int { 
    return rhs*rhs 
} 

var a : Int = 2 
var b : Int = *a // 4 

Um dies zu einpacken: Einige Betreiber besteht nativ in Swift sowohl als Präfix und Infixoperatoren, z.B.-

/* Declared natively in Swift */ 
infix operator - { 
    associativity left 
    precedence 140 
} 

prefix operator - { 
} 

/* Example usage */ 
let a : Int = 2 - 1 // 1, '-' infix operator used 
let b : Int = -1 // -1, '-' prefix operator used 

während andere, wie * wird nur (nativ) als Infixoperator verwendet.

Beachten Sie auch, dass, wenn Sie Ihre eigenen benutzerdefinierten Infixoperatoren definieren wollen, werden ihre zulässigen Namen eingeschränkt wie folgt:

Benutzerdefinierte Operatoren mit einem der ASCII-Zeichen beginnen kann /, =, -, + ,!, *,%, <,>, &, |, ^,?, Oder ~ oder eines der in der folgenden Grammatik definierten Unicode-Zeichen (einschließlich Zeichen aus Mathematische Operatoren, Verschiedene Symbole und Dingbats Unicode Blöcke, unter anderem). Nach dem ersten Zeichen sind auch Unicode Zeichen erlaubt.

Von Language Reference - Lexical Structure.