You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何定义返回Binding的函数/闭包,解决inout报错并实现泛型适配

报错原因

  • inout 参数采用 copy-in copy-out 的传递规则,生命周期仅覆盖函数调用阶段。Binding 的 get、set 属于逃逸闭包,需要在函数返回后仍可访问值的存储地址,因此编译器禁止逃逸闭包捕获 inout 参数,抛出对应错误。

修正后的泛型实现

移除 inout 参数,设计泛型接口适配任意值类型:

func makeBinding<T>(get: @escaping () -> T, set: @escaping (T) -> Void) -> Binding<T> {
    Binding(get: get, set: set)
}

如果需要针对实例的存储属性快速生成Binding,可结合可写键路实现更简洁的调用:

func makeBinding<T, Root>(for instance: Root, keyPath: WritableKeyPath<Root, T>) -> Binding<T> {
    Binding(
        get: { instance[keyPath: keyPath] },
        set: { instance[keyPath: keyPath] = $0 }
    )
}

使用示例

  • 生成任意类型的Binding
// CGFloat 类型场景
var coverOpacity: CGFloat = 0.8
let opacityBinding = makeBinding { coverOpacity } set: { coverOpacity = $0 }

// Bool 类型场景
var showAlert: Bool = false
let alertBinding = makeBinding { showAlert } set: { showAlert = $0 }
  • 键路方式生成实例属性的Binding
class AppConfig: ObservableObject {
    var cornerRadius: CGFloat = 12
    var enableHaptic: Bool = true
}

let globalConfig = AppConfig()
let radiusBinding = makeBinding(for: globalConfig, keyPath: \.cornerRadius)
let hapticBinding = makeBinding(for: globalConfig, keyPath: \.enableHaptic)

提示:如果是在SwiftUI View内针对@State、@StateObject等属性生成Binding,直接使用$前缀即可获得对应类型的Binding,无需额外调用封装函数。

内容的提问来源于stack exchange,提问作者swiftPunk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 18:36:07