2016-01-26 20 views
6

私はこれを行っているのを見たことがありますが、私はそれの周りに私の頭を包むことはできません。どうやら、一見魔法のように、いくつかの中置関数は正常に機能しますが、他の関数は単純にコンパイルされません。たとえば、次のようにSwiftインフィックス関数を書くにはどうすればいいですか?

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

あなたがここに見るように、伝統的な機能としてではなく、中置一つとして私のthen機能の仕事、まだ私の* 1は反対の問題があります。 私のthen機能をインフィニクス機能とするには、どのような魔法のソースがありますか?

サイド質問:私の*機能が従来の機能として機能しないのはなぜですか?

テキストのみの読者のための

コードとコピー&ペーストを:

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

ここでは、インフィックス演算子でhttps://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AdvancedOperators.htmlを参照することをお勧めします。 –

答えて

6

スウィフト標準ライブラリがすでに中置演算子として*定義:

infix operator * { 
    associativity left 
    precedence 150 
} 

あなたは見つけることができます Swift Standard Library Operators Referenceの事前定義された演算子のリスト。あるいは、Xcodeのimport Swift文で "command-click"をクリックし、 "operator"を検索してください。

「伝統的な」関数呼び出しで演算子を使用するには、括弧で囲む必要があります:

(*)("Left", 6) 

独自の中置演算子を定義したい場合は、あなたが infix operator宣言を追加する必要があります。ただし、オペレータには 文字の制限されたセットだけが有効です(詳細なルールについては、Language Reference->Lexical Structure->Operatorsを参照してください)。特に、オペレータ は、 /、=、 - 、+、!、*、%、<、>、&、|、^、?、〜、または他のいくつかの "記号 "の文字。特に、 "then"は有効な演算子名ではありません。

+1

偉大な答え。 Swiftの標準ライブラリでは、これらの挿入演算子はどこに宣言されていますか?私はモジュールを通してやって、これらの仕組みを見てみたいと思う。 – JAL

+1

@ JAL:宣言のために、「Swift」をSwiftと呼びます。遊び場。 – dfri

+1

@ JAL:...またはここ:https://developer.apple.com/library/ios//documentation/Swift/Reference/Swift_StandardLibrary_Operators/index.html –

2

*は既にスウィフトバイナリ中置演算子として、ネイティブに、定義される:

infix operator * { 
    associativity left 
    precedence 150 
} 

したがって、フォームfunc * (...の任意の関数が、このバイナリ中置演算子をオーバーロードされています。あなたは接頭辞単項演算子として*演算子を使用しようとする一方で、あなたは*が接頭辞としてネイティブに存在していないだけであるため、*は接頭辞単項演算子ではない」という記述エラーが発生しますオペレーター。

あなたはもちろん、独自の接頭オペレータ*定義することができます。これをラップするには

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

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

を:いくつかの演算子は、プレフィックスと中置演算子として両方スウィフトでネイティブに存在する、例えば他の一方-

/* 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 

など*は、ちょうど(ネイティブ)中置演算子として使用されます。 - 、 +

カスタム演算子は、ASCII文字の1 /、=、で始めることができます。

はまた、独自のカスタム中置演算子を定義したい場合は、以下のように、その許可名が拘束されていることに注意してください|、^、?、または〜、または以下の文法で定義されているUnicode文字の1つ( の演算子、その他のシンボル、およびDingbats Unicode の文字が含まれていますブロックなど)。最初の文字の後にUnicode 文字を組み合わせることもできます。

Language Reference - Lexical Structure

関連する問題