SwiftUI如何使用字符串字面量在Text中创建一个LocalizedStringKey?

huangapple go评论66阅读模式
英文:

How is SwiftUI able to use string literals in Text to create a LocalizedStringKey?

问题

我想让我的自定义视图像 Text 一样工作。如果我传递一个字符串文字,我希望它使用 LocalizedStringKey 创建,如果我传递一个变量,我希望它被视为字符串(类似于 verbatim:)。我做了一个小测试,使用与 Text 的 init 相同的签名,如果我传递一个字面量,它就会进入 StringProtocol 的 init。这在 Text 中是如何实现的?

英文:

I would like to have my custom views work like Text. If I pass a string literal, I would like it to be created using LocalizedStringKey, and if I pass a variable, I would like it to be treated as a String (likewise with verbatim:). I did a little test, and using the same signatures on init as Text, if I pass a literal, it goes to the StringProtocol init. How is this done with Text?

答案1

得分: 2

> 我做了一个小测试,如果我在初始化时使用与 Text 相同的签名,如果我传递一个文字,它会调用 StringProtocol 的初始化。

我猜你做了类似这样的事情:

init<S: StringProtocol>(_ x: S) {}
init(_ x: LocalizedStringKey) {}

你发现第一个重载总是被调用。

可以通过在 StringProtocol 重载上标记 @_disfavoredOverload 来修复这个问题。请注意,由于这个名称前面有一个下划线,它不是一个稳定的功能,可能会在将来更改。

但这确实是 SwiftUI 中 Text 使用的方式(至少目前是这样)。@_disflavoredOverload这个 markdown 文件 中有文档。那里的示例显示了与 LocalizableStringKey 相关的确切问题:

> extension LocalizedStringKey: ExpressibleByStringLiteral { ... }
>
> extension Text {
> // 我们希望 Text("foo") 使用这个初始化程序:
> init(_ key: LocalizedStringKey) { ... }
>
> // 但是,如果没有 @_disfavoredOverload,它会使用这个初始化程序,
> // 因为这样可以让它给文字以其默认类型:
> @disfavoredOverload init<S: StringProtocol>( str: S) { ... }
> }

英文:

> I did a little test, and using the same signatures on init as Text, if I pass a literal, it goes to the StringProtocol init.

I suppose you did something like this:

init&lt;S: StringProtocol&gt;(_ x: S) {}
init(_ x: LocalizedStringKey) {}

And you found that the first overload is always being called.

This can be fixed by marking the StringProtocol overload with @_disfavoredOverload. Note that since this has an underscore prefix, it is not a stable feature and might change in the future.

But this is indeed what Text in SwiftUI uses (at least for now). @_disflavoredOverload is documented in this markdown file. The example there shows this exact problem with LocalizableStringKey:

> extension LocalizedStringKey: ExpressibleByStringLiteral { ... }
>
> extension Text {
> // We want Text(&quot;foo&quot;) to use this initializer:
> init(_ key: LocalizedStringKey) { ... }
>
> // But without @_disfavoredOverload, it would use this one instead,
> // because that lets it give the literal its default type:
> @disfavoredOverload init<S: StringProtocol>( str: S) { ... }
> }

huangapple
  • 本文由 发表于 2023年6月18日 20:01:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76500436.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定