gpt4 book ai didi

swift - 如何在没有样板的情况下从父类(super class)访问内部对象的属性

转载 作者:行者123 更新时间:2023-11-28 11:30:47 24 4
gpt4 key购买 nike

有没有一种方法可以在没有样板的情况下创建内部对象属性的访问器?

这是一个带有样板的类的例子

public class Foo {
internal let bar: Bar

internal init(bar: Bar) {
self.bar = bar
}

private struct Bar: Codable {
let id: Int
let name: String
}

// MARK: - Boilerplate

public var id: Int {
return self.bar.id
}

public var name: String {
return self.bar.name
}
}

// Usage

do {
let bar: Bar = try data.decoded()
let foo = Foo(bar: bar)

print(foo.id)
print(foo.name)
} catch {
...
}

有没有办法不用写样板文件就可以做到这一点?对于具有更多属性的更大对象,这可能非常有用

注意:访问控制修饰符很重要

最佳答案

Swift 5.1 中的新功能,您可以使用带有键路径的动态成员查找。这对于这种“有一个”的情况非常有效,因为关键路径保持完整的类型检查。这是一个简化的示例(没有尝试反射(reflect)您的实际情况):

struct Dog {
let name : String
}
@dynamicMemberLookup
struct Kennel {
let dog : Dog
subscript(dynamicMember kp:KeyPath<Dog,String>) -> String {
self.dog[keyPath:kp]
}
}

结果是,给定一个 Kennel k,我们可以获得 k.name 作为获取 k.dog.name 的方法.

但是说 k.xxx 是非法的,因为 Dog 没有 String xxx 属性;这就是我所说的完整类型检查得到维护的意思。


旧方法是使用协议(protocol)。这样您就可以使用协议(protocol)扩展来注入(inject)样板文件。

protocol HasNameAndId {
var id: Int {get}
var name: String {get}
}

protocol WrapperOfHasNameAndId {
associatedtype T : HasNameAndId
var bar: T {get}
}

extension WrapperOfHasNameAndId { // boilerplate
var id: Int {
return self.bar.id
}
var name: String {
return self.bar.name
}
}

// ==============

struct Bar: HasNameAndId {
let id: Int
let name: String
}

class Foo : WrapperOfHasNameAndId {
let bar: Bar
init(bar: Bar) {
self.bar = bar
}
}

// =======

let f = Foo(bar: Bar(id: 1, name: "howdy"))
print(f.id) // 1
print(f.name) // "howdy"

关于swift - 如何在没有样板的情况下从父类(super class)访问内部对象的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56782925/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com