2016-12-02 28 views
5

在Swift 3中,我編寫了一個自定義運算符prefix operator §,我使用的方法是將String作爲返回LocalizedString結構的值(保存鍵和值)。Swift:與點(「。」)相關的自定義運算符的優先級

public prefix func §(key: String) -> LocalizedString { 
    return LocalizedString(key: key) 
} 

public struct LocalizedString { 
    public var key: String 
    public var value: String 

    public init(key: String) { 
     let translated = translate(using: key) // assume we have this 
     self.key = key 
     self.value = translated ?? "!!\(key)!!" 
    } 
} 

(是的,我知道的真棒L10n enum in SwiftGen,但我們從我們的後臺下載我們的字符串,這個問題更多的是如何與運營商定製合作)

但是,如果我們想要得到的從§操作符的結果轉換值(即,從所得到的LocalizedString屬性value

let translation = §"MyKey".value // Compile error "Value of type 'String' has no member 'value'" 

我們當然可以容易地通過包木窗它解決這個編譯錯誤在括號(§"MyKey").value中。但如果不想這樣做。 是否可以爲自定義運算符設置與'點'文字關係的優先級?

是的,我知道,只有綴運營商可以聲明優先級,但它會是有意義的,以便與優先莫名其妙地工作,以實現我想要什麼:

precedencegroup Localization { higherThan: DotPrecedence } // There is no such group as "Dot" 
prefix operator §: Localization 

爲了紀念該斯威夫特編譯器首先應該評估§"MyKey"並明白這不是一個字符串,但實際上是一個LocalizedString(結構)。

覺得這不可能是不可能的?我錯過了什麼?

+0

我試過但找不到任何方法,也許我們需要提交一個雷達,但是我很困惑,如果這真的可以稱爲bug。 –

回答

5

.不像標準庫中定義的所有其他操作符,它由編譯器提供。它的語法是Explicit Member Expressions

.更高的優先級不是編譯器應該允許你做的事情,因爲它是一個基本的用例。想象一下,你可以做什麼,如果編譯器啓用了這樣一件事:如果你能有比.更高的優先級

-"Test".characters.count 

,編譯器必須檢查所有可能:

(-"Test").characters.count // func -(s: String) -> String 
(-("Test".characters)).count // func -(s: String.CharacterView) -> String.CharacterView 
-("Test".characters.count) // func -(s: Int) -> Int 

這會

  • 潛在增加編譯時間很多
  • 含糊不清
  • 在添加重載

我建議你做的是放棄與新運營商的想法是什麼可能改變現有代碼的行爲,它一定會被擠壓一些具體的行爲變成一個模糊的增加更多的認知負荷字符。這是我想做到這一點:

extension String { 
    var translatedString : String { 
     return translate(using: self) 
    } 
} 

"MyKey".localizedString 

或者,如果你想用你的LocalizedString

extension String { 
    var localized : LocalizedString { 
     return LocalizedString(key: self) 
    } 
} 

"MyKey".localized.value 

這些版本更爲全面。