gpt4 book ai didi

swift - 如何跨具有冲突属性名称的结构实现 Swift 协议(protocol)

转载 作者:行者123 更新时间:2023-12-05 01:11:11 24 4
gpt4 key购买 nike

我正在尝试编写一个协议(protocol)来协调描述相同概念的两个不同结构,某种停止。两者都有 Code , Description , 和 Latitude & Longitude坐标,但对于一种类型,Description可能是 nil ,对于其他类型,坐标可能是 nil .

如何编写一个协调这两个结构的协议(protocol)?

这是我的协议(protocol):

protocol Stop {
var Code : String { get }
var Description : String { get }
var Latitude : Double { get }
var Longitude : Double { get }
}

以及两种类型的停止:
struct BusStop : Stop {  // Compiler error: doesn't implement Description
var Code : String
var Description : String?
var Latitude : Double
var Longitude : Double
// Various other properties
}

struct TrainStop : Stop { // Compiler error: doesn't implement Latitude or Longitude
var Code : String
var Description : String
var Latitude : Double?
var Longitude : Double?
// Various other properties
}

在 C#(我的母语)中,我会像这样(伪代码)编写一个显式接口(interface)实现:
// At the end of the BusStop struct
var Stop.Description : String { return Description ?? string.Empty }

// At the end of the TrainStop struct
var Stop.Latitude : Double { return Latitude ?? 0 }
var Stop.Longitude : Double { return Longitude ?? 0 }

但是,我不知道 Swift 中有任何类似的功能。鉴于我无法更改 BusStop 的现有属性定义和 TrainStop ,我怎么写 Stop协议(protocol),以便它包含两个结构并在可用时返回属性?

最佳答案

显式接口(interface)实现的期望特性是它们是静态分派(dispatch)的,对吗?如果您使用 DescriptionBusStop ,它将是一个可选字符串,但如果您使用 DescriptionStop ,它将是一个非可选字符串。

在 Swift 中,扩展成员是静态分派(dispatch)的,因此您可以利用它来实现类似的功能:

extension Stop where Self == BusStop {
// Since the type of "self" here is BusStop, "Description" refers to the one declared in BusStop
// not this one here, so this won't cause infinite recursion
var Description : String { return self.Description ?? "" }
}

extension Stop where Self == TrainStop {
var Latitude: Double { return self.Latitude ?? 0 }
var Longitude: Double { return self.Longitude ?? 0 }
}

这段代码表明这是有效的:
let busStop = BusStop(Code: "ABC", Description: "My Bus Stop", Latitude: 0, Longitude: 0)
print(type(of: busStop.Description)) // Optional<String>
let stop: Stop = busStop
print(type(of: stop.Description)) // String

但是,我仍然认为这不是好的 Swift 代码。直接将 API 从一种语言翻译成另一种语言通常是不好的。如果我是你,我会做 Longitude , LatitudeDescriptionStop都是可选的。

关于swift - 如何跨具有冲突属性名称的结构实现 Swift 协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58280827/

24 4 0