【问题标题】:Converting optional Binding to non-optional Binding将可选绑定转换为非可选绑定
【发布时间】:2021-10-03 09:39:40
【问题描述】:

我想用一个 func 扩展 Binding 扩展,我们可以将可选的 Binding 转换为非可选的 Binding 并将其用作普通的 Binding。我几乎可以完成它,但是 xCode 通过一个我无法处理的错误,我认为我做的一切都是正确的。

extension Binding {
    
    mutating func safeBinding<T>(defaultValue: T) -> Binding<T> where Value == Optional<T> {
        
        let safeValue: T
        
        if let unwrappedValue: T = self.wrappedValue { safeValue = unwrappedValue }
        else { safeValue = defaultValue }

        return Binding.init(get: { () -> T in return safeValue },
                            set: { (newValue) in self.wrappedValue = newValue })
 
        
    }
}

错误:

Cannot convert return expression of type 'Binding<Optional<T>>' to return type 'Binding<T>'

为我的方式更新了代码:

extension Binding {
    
     func safeBinding<T>(defaultValue: T) -> Binding<T> where Value == Optional<T> {
        
        let safeValue: T
        
        if let unwrappedValue: T = self.wrappedValue { safeValue = unwrappedValue }
        else { safeValue = defaultValue }

        return SwiftUI.Binding.init(get: { () -> T in return safeValue },
                                    set: { (newValue) in self.wrappedValue = newValue })
 
        
    }
}

【问题讨论】:

    标签: swift swiftui


    【解决方案1】:

    Binding 已经有一个关联类型 Value,因此通过尝试使用 T,您将在已经存在的 Value 之上放置一个新的泛型。

    但是,您最终仍将使用 T,因为您希望将 Value 限制在可选的场景中:

    extension Binding {
        func safeBinding<T>(defaultValue: T) -> Binding<T> where Value == Optional<T> {
            .init {
                self.wrappedValue ?? defaultValue
            } set: { newValue in
                self.wrappedValue = newValue
            }
        }
    }
    

    如 cmets 中所述,如果只使用 Binding.init,Xcode 编译器会遇到困难(请注意,我只使用了 .init)。这可以通过显式使用Binding&lt;T&gt;.init 来解决:

    extension Binding {
        func safeBinding<T>(defaultValue: T) -> Binding<T> where Value == Optional<T> {
            Binding<T>.init {
                self.wrappedValue ?? defaultValue
            } set: { newValue in
                self.wrappedValue = newValue
            }
        }
    } 
    

    【讨论】:

    • 我注意到你使用的是.init,如果我们像Binding.init一样在它前面使用Binding,它就不起作用了!为什么?我们没有使用 Binding init 吗?
    • 你只需要更明确地输入并使用Binding&lt;T&gt;.init——编译器应该能够推断出这一点,但由于某种原因,它不能。
    • 我在您编辑问题以使用Value == Optional&lt;T&gt;(这解释了我的第一句话)之前写了我的答案,但是是的,看起来在那之后,它只是对代码的简化。就像我说的,使用Binding&lt;T&gt;.init 有效。
    • 我们必须使用SwiftUI.Binding.init 所以说我该如何重构我的原始代码!?
    • 我发现了!我更新了代码!我应该明确地使用SwiftUI.Binding.init 并且省略变异。 :)
    猜你喜欢
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 2015-03-15
    • 1970-01-01
    • 2012-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多