2017-10-13 126 views
1

這裏使用一個建議圖案Intl.message我已經隨處可見:爲什麼intl.Message需要封裝在封閉函數中?

final String learnMoreLabel = _learnMoreLabel; String get 
_learnMoreLabel => Intl.message('Learn more', 
    name: 'HelpContentBase__learnMoreLabel', 
    desc: 'The label for a link or button which takes the user to the ' 
     'Google Help Center to read more information on a topic.'); 

爲什麼我不能只是寫:

final String learnMoreLabel = Intl.message('Learn more', 
    name: 'HelpContentBase__learnMoreLabel', 
    desc: 'The label for a link or button which takes the user to the ' 
     'Google Help Center to read more information on a topic.'); 

爲什麼它需要被包裹在吸氣?我在the docs中發現了這一點:

將此消息用於將被翻譯爲不同語言環境的消息。 預期的用法是它位於一個封閉函數中, 僅返回此調用的值,併爲將在消息中替換的 變量提供一個範圍。

但它不會說爲什麼

回答

2

簡短的回答是,對於那個例子來說,它可能是這樣寫的,但是當有消息的參數時它會被打破。

Intl消息會發生什麼情況是預處理器運行該程序並查找Intl.message的所有事件並將它們寫入文件。該文件被髮送用於翻譯,然後翻譯通過另一程序運行併爲每種語言生成Dart代碼,可通過messages_all.dart導入到達。

當您在運行時調用Intl.message時,它會查找當前語言環境(使用該名稱作爲鍵)並委託給相應的翻譯,並傳遞任何參數(通過「args」參數)。

當註釋中顯示「提供了一個作用域」時,這實際上意味着該消息中唯一允許使用的東西是作爲參數提供給封閉函數的變量。當沒有任何參數時,我們可以讓封閉函數被省略。這意味着使解析器足夠聰明以識別該模式。

另一方面:我不喜歡調用方法一次並賦值給最終變量的模式。它在區域設置初始化和變量初始化之間設置了潛在的競爭條件,這意味着區域設置在運行時不能改變。但是,我明白,當我們有像Angular這樣的框架調用它並比較每個框架上的結果時,實際上每次調用函數都會變得很昂貴。

另一方面:如果沒有參數,可以省略名稱。它將使用文本作爲名稱。當有參數時,文本是插值的,所以它不能用它作爲名稱。