现在我正在使用一个有很多可选属性的类。对于一些可选属性,我希望能够采用不同的类型,并且基本上将它们转换为我想要存储它的类型,以方便用户。例如,用户可以提供Date
,String
或Int
来指示特定日期。这是我正在尝试做的一个例子。 (忽略我正在做一个可能不安全的包装的事实。)
class SOExample {
let value: Int
let time: Double?
init(value: Int, time: Double? = nil) {
self.value = value
self.time = time
}
convenience init(value: Int, time: Int? = nil) {
if time != nil {
self.init(value: value, time: Double(time!))
} else {
self.init(value: value, time: nil)
}
}
}
当我尝试在没有任何选项的情况下初始化时出现问题 - 它不知道要使用什么初始化程序。例如,SOExample(value: 7)
在单元测试中将其返回:
error: ambiguous use of 'init(value:time:)'
let soExample = SOExample(value: 7)
^
<unknown>:0: note: found this candidate
<unknown>:0: note: found this candidate
<unknown>:0: error: build had 1 command failures
我怎样才能做我想做的事情?我是以完全错误的方式来做这件事的吗?我应该使用除多个初始值设定项之外的其他内容来执行此操作吗?
答案 0 :(得分:1)
您可以通过删除其中一个初始化函数中不需要的参数来解决此问题。
答案 1 :(得分:0)
解决问题的最简单方法是在便捷方法中重命名第二个参数。当你传递nil导致你的问题时,两个初始化方法的签名是相同的。我不确定这是否适合你的情况。
class SOExample {
let value: Int
let time: Double?
init(value: Int, time: Double? = nil) {
self.value = value
self.time = time
}
convenience init(value: Int, timeAsInt: Int? = nil) {
if timeAsInt != nil {
self.init(value: value, time: Double(timeAsInt!))
} else {
self.init(value: value, time: nil)
}
}
}
鉴于两种方法的签名是相同的,并且您不能对具有不同类型和默认值nil的第二个参数使用相同的标签,您可以为您的类创建一个静态方法,该方法将采用一种类型Any
然后解决可能的情况。
class SOExample {
let value: Int
let time: Double?
init(value: Int, time: Double? = nil) {
self.value = value
self.time = time
}
static func make(value: Int, time: Any? = nil) -> SOExample {
if time != nil {
// Int
if let timeInt = time as? Int {
return SOExample(value: value, time: Double(timeInt))
}
// String
if let timeString = time as? String {
if let timeDouble = Double(timeString) {
return SOExample(value: value, time: timeDouble)
}
}
}
return SOExample(value: value)
}
}
然后你会像这样使用它:
let exampleOne = SOExample.make(value: 4, time: 4)
let exampleTwo = SOExample.make(value: 4, time: "4")
答案 2 :(得分:0)
根据Eugene Zhenya Gordin的建议,可以通过删除convenience init
初始化程序中的可选组件来解决此问题。如果我们只希望在time
参数为Int
时调用初始化程序,那么该变量应该成为该特定init
所必需的。这解决了这种情况下的模糊性。
class SOExample {
let value: Int
let time: Double?
init(value: Int, time: Double? = nil) {
self.value = value
self.time = time
}
convenience init(value: Int, time: Int) {
self.init(value: value, time: Double(time))
}
}
这并不允许我使用Int?
作为参数类型,因为最终这看起来像是无法解决的模糊性。不妨强迫它,因为无论如何这对我的应用程序来说效果都不错。