2017-01-18 16 views
5

Próbuję zdefiniować niestandardowego operatora w Swift z grupą pierwszeństwa wyższą niż zamknięcie. W szczególności chcę, aby móc napisać:Grupa pierwszeństwa wyższa niż zamknięcie

foo --> bar { 
    //... 
} 

Operator --> zwraca funkcję, która pobiera zamknięcie typu () -> Void jak jest to jedyny parametr.

Jednak mam tylko udało się dostać

(foo --> bar) { 
    //... 
} 

do pracy. Czy istnieje pierwszeństwo operatorów, które może działać bez nawiasów?

Oto grupa pierwszeństwo dla

precedencegroup LongArrowPrecedence { 
    associativity: left 
    higherThan: AssignmentPrecedence 
} 

infix operator --> : LongArrowPrecedence 

Dzięki!

Odpowiedz

5

Najpierw utwórz kompletny i zweryfikowania przykład:

precedencegroup LongArrowPrecedence { 
    associativity: left 
    higherThan: AssignmentPrecedence 
} 

infix operator --> : LongArrowPrecedence 

func -->(lhs: Int, rhs: Int) -> (() ->()) ->() { 
    return { print(lhs+rhs, terminator: ""); $0() } 
} 

jak również przykłady nawiasach-objął ważnych połączeń za pomocą tego operatora natychmiast następuje wezwanie do zamknięcia, które --> zwrotów.

let foo = 1 
let bar = 2 

// OK 
(foo --> bar) { 
    print(" is the magic number") 
} // 3 is the magic number 

// OK 
((-->)(foo, bar)) { 
    print(" is the magic number") 
} // 3 is the magic number 

to nie mówi nam wiele, ale jeśli badamy następujące przypadki upadających

// ERROR: cannot call value of non-function type 'Int' 
foo --> bar { 
    print(" is the magic number") 
} // 3 is the magic number 

// ... equivalent to 
// ERROR: cannot call value of non-function type 'Int' 
foo --> bar({ 
    print(" is the magic number") 
}) // 3 is the magic number 

Zdajemy sobie sprawę, że problem nie jest tu „pierwszeństwo niższe niż zamknięcie”, ale raczej że function-call-argument-clause (zbiór paranthezy po dowolnym wyrażeniu Postfiks) spróbuje wywołać wywołanie dla tego postfiksowego wyrażenia, tak jakby wyrażenie postsfiksowe było metodą/funkcją/zamknięciem. Jeśli wyrażeń postfiksowych nie można wywołać lub jeśli wywołanie w klauzuli function-call-argument nie odpowiada żadnemu przeciążeniu wywoływanego, kompilator wygeneruje błąd.

42()   // ERROR: cannot call value of non-function type 'Int' 
let foo = 42 
foo()   // ERROR: cannot call value of non-function type 'Int' 

func bar() {} // ERROR: argument passed to call that takes no arguments 
bar(42) 

Stąd zamknięcie tylnej dostarczane do zamknięcia wrócił z --> nie ma znaczenia tutaj: to po prostu argumentem do zwracanego zamknięcia, a kluczową kwestią jest to, że Swift będzie zastosowanie funkcji-Call-argumentu-klauzulę do wyrażeń postfiksowych, które bezpośrednio poprzedzają klauzulę. Na przykład: bar stanowi wyrażenie postfiksowe i tylko jeśli opakujesz foo --> bar w parantezach, połączone wyrażenie zawijane będzie stanowić wyrażenie postfiksowe, do którego zostanie zastosowana następująca klauzula-wywołania-funkcji-argumentu.

wyrażenia Postfix Ekspresja

Postfix są utworzone przez nakładanie operator postfix lub innego składni postfix do ekspresji. Syntaktycznie każde podstawowe wyrażenie jest również wyrażeniem postfiks.

Podstawowe wyrażenia

wyrażenia pierwotne są najbardziej podstawowy rodzaj ekspresji. Mogą być one używane jako wyrażenia samodzielnie i można je łączyć z innymi tokenami , aby uzyskać wyrażenia przedrostkowe, wyrażenia binarne i postfiksy .

Nie można tego obejść, ponieważ pierwszeństwo operatora nie ma zastosowania do klauzuli wywołania funkcji; ten ostatni (i jego "pierwszeństwo") jest definiowany przez gramatykę wyrażenia wywołania funkcji.

Powiązane problemy