2017-10-13 129 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这样的框架调用它并比较每个框架上的结果时,实际上每次调用函数都会变得很昂贵。

另一方面:如果没有参数,可以省略名称。它将使用文本作为名称。当有参数时,文本是插值的,所以它不能用它作为名称。