Swift 协议(protocol)扩展 : cannot assign to property: '' is a get-only property

标签 swift

我想我不明白协议(protocol)扩展应该如何工作。

我试过这个:

protocol P {
    var h: [String: Any] { set get }
}

extension P {
    var h: [String: Any] {
        get {
            return [:]
        }
        set {}
    }
}

struct S: P {   
    init() {
        self.h = ["o": "o"]
    }
}

我的目标是 S 具有 P 的属性,并且不需要在结构定义中重新声明它。

但是,当我创建 let s = S() 时,s.h 始终等于 [:] 而不是 ["o ":"o"].

当然,这是因为我的setter是空的,但是我不知道如何去做我想在这里实现的。

感谢您的帮助。

最佳答案

My goal is that S has the properties of P and doesn't need to re-declare it in the struct definition.

这在您尝试执行此操作的方式中是不可能的。协议(protocol)需要某些行为。符合类型必须提供这些行为。如果您需要存储来实现行为,则符合类型必须提供存储。

如果您不需要存储也没关系,那么扩展程序可以像您的一样返回值。但是您不能返回计算值并且也有存储空间。你想做的事是不可能的。您正在考虑类,而不是协议(protocol)。 (如果你想要类,那很好。使用类。它们没有任何问题。)

思考为什么这在 Swift 中不可能的一个好方法是考虑以下情况。假设您的 P 协议(protocol)以某种形式存在,可以实现您想要的。现在在一个模块中我们定义:

struct S {}

这个结构不需要存储。在该模块中对 S() 的任何调用都不会分配任何内容。 (或者,给 S 一些属性,它会分配一些特定数量的内存。)

现在在其他一些模块中,扩展 S 以符合 P:

extension S: P {}

h 的存储空间在哪里?在加载此扩展时,实例可能已经存在。如果有多个协议(protocol)需要额外的存储并且所有协议(protocol)都附加到 S 会怎么样。 S 结构中的那些属性应该是什么偏移量?该顺序对于编译代码非常重要。这并非不可能解决(ObjC 使用一种称为关联对象的技术来解决),但它是对语言的一个很大的补充,并且阻止了许多重要的优化,而 Swift 不会那样做。

关于Swift 协议(protocol)扩展 : cannot assign to property: '' is a get-only property,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54135006/

相关文章:

ios - 在 Swift 类或结构中声明为静态的变量会发生什么

ios - Swift - UICollectionView removeAll() 暂时清除单元格

xcode - 在 OSX 上的 Swift 中使用 setFrameOrigin 将 NSView 添加到 super View 后居中

ios - TabBar 的背景颜色在选项卡选择时发生变化

ios - 将 UITableView 选择添加/删除到数组,滚动时复选标记消失 - Swift

ios - NSPredicate 查找具有相同标签形式的 UIView self.view.subviews Swift

ios - 在两个静态 UITableViewCell 之间插入带有 UIPickerView 的行时出现 NSRangeException

ios - PFArrayResultBlock(parse) 在转换为 swift 2.0 时导致错误

ios - 在 iOS 上运行小型周期性高优先级后台任务

swift - 将本地 Realm 转换为同步 Realm : 'customSchema' is inaccessible