英文:
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<S: StringProtocol>(_ 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("foo")
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) { ... }
> }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论