gpt4 book ai didi

swift - 如何使用内部协议(protocol)的初始值设定项在公共(public)函数中构造新值?

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

假设我想将一些功能公开为公共(public) API,但部分实现涉及内部协议(protocol):

public protocol P {
var foo: Int { get }
}

internal protocol Q {
init(from: [String])
}

public struct S: P, Q {
public var foo: Int = 0
public init() {}

internal init(from: [String]) {
precondition(from.count > 0)
self.foo = Int(from[0])!
}
}

这将是一些数据对象,只有我自己的模块可以构造(从一些数据表示)但是模块的用户可以出于他们自己的目的使用。

假设我想提供一些接受这样的值并返回相同类型的新值的服务:

public class ProviderOfThings {
public func map<T: P>(before: T) -> T {
return T(from: [String(before.foo + 1)])
}
}

这不会编译; T 上没有合适的初始化程序。

如何以通用方式调用我(内部)知道的构造函数?

最佳答案

我们可以将值转换为内部协议(protocol)类型并从那里访问初始化程序:

public static func map<T: P>(before: T) -> T {
return type(of: before as! Q).init(
from: [String(before.foo + 1)]
) as! T
}

我们甚至可以不用类型的值(谢谢,Hamish!):

public static func make<T: P>() -> T {
return (T.self as! Q.Type).init(
from: ["0"]
) as! T
}

如果有(或可能有)P 的实现不符合 Q,则需要转换为 Q守卫,显然:

guard let beforeQ = before as? Q else { ... }
// or
guard before is Q else { ... }

// respectively
guard T.self is Q.Type else { ... }

另一个将 转换为! T 是安全的:毕竟我们调用了 T 的初始值设定项。因此,如果受到保护,该解决方案不会导致运行时错误。

查找带有示例的完整代码 here .

关于swift - 如何使用内部协议(protocol)的初始值设定项在公共(public)函数中构造新值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42514600/

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