在 Xcode11 Beta 4 中使用 String(format: , args) 和 SwiftUI 时出错



升级到Xcode 11 Beta 4后,我在使用带有@State属性的String(format: , args)时开始看到错误。 请参阅下面的代码。 第二行Text引发错误:

表达式类型"字符串"不明确,没有更多上下文

Text s 1、3 和 4 工作正常。

struct ContentView : View {
    @State var selection = 2
    var body: some View {
        VStack {
            Text("My selection (selection)") // works
            Text("My selection (String(format: "%02d", selection))") // error
            Text("My selection (String(format: "%02d", Int(selection)))") // works
            Text("My selection (String(format: "%02d", $selection.binding.value))") // works
        }
    }
}

我意识到这是 Beta 版软件,但很好奇是否有人可以看到这种行为的原因,或者这只是一个错误。 如果这无法解释,我将提交雷达。

在 beta 4 中,属性包装器实现略有变化。在 beta 3 中,编译器将视图重写为:

internal struct ContentView : View {
  @State internal var selection: Int { get nonmutating set }
  internal var $selection: Binding<Int> { get }
  @_hasInitialValue private var $$selection: State<Int>
  internal var body: some View { get }
  internal init(selection: Int = 2)
  internal init()
  internal typealias Body = some View
}

而在 Beta 4 上,它这样做:

internal struct ContentView : View {
  @State @_projectedValueProperty($selection) internal var selection: Int { get nonmutating set }
  internal var $selection: Binding<Int> { get }
  @_hasInitialValue private var _selection: State<Int>
  internal var body: some View { get }
  internal init(selection: Int = 2)
  internal init()
  internal typealias Body = some View
}

现在我猜:此更改使编译器更难推断变量的类型?请注意,另一种有效的替代方法是通过强制转换selection as Int来帮助编译器:

Text("My selection (String(format: "%02d", selection as Int))")

更新 (Xcode 11.2(

我也收到错误:

'inout Path' is not convertible to '@lvalue Path'

使用此代码:

struct ContentView : View {
    @State var selection = 2
    var body: some View {
        VStack {
            Text(String(format: "%d", selection)) // does not work
        }
    }
}

通过添加 $ 前缀然后访问wrappedValue来解决 String(format:, args:)

struct ContentView : View {
    @State var selection = 2
    var body: some View {
        VStack {
            Text(String(format: "%d", $selection.wrappedValue)) // works
        }
    }
}

最新更新