2016-11-28 78 views
0

现在我正在处理一个具有很多可选属性的类。对于这些可选属性中的一些,我希望能够采用不同的类型,并基本上将它们转换为我想要存储的类型,以方便用户。例如,用户可以提供DateStringInt来指示某个日期。这是我想要做的一个例子。 (忽略,我做一个潜在的不安全包装的事实。)可选参数可以具有不同类型时模糊Swift初始化器

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 

如何将我能够做我想要做什么?我是否完全错误的方式?我应该使用除多个初始化程序之外的其他功能来执行此操作吗?

+1

你可以从一个inits中删除不需要的参数吗? –

+1

你能举一个更有意义的例子吗?你的代码崩溃是因为你打开了一个'nil'值,而'fooDouble:Int'显然是无意义的。 – luk2302

+0

@EugeneZhenyaGordin确实做到了!现在我对这个问题感到无聊。随意张贴,作为答案。 – TheSoundDefense

回答

0

至于建议由Eugene振亚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?作为参数类型,不过,因为最终,看起来像一个无法解决的歧义。不妨强制它,因为无论如何这对我的应用程序来说足够好。

1

您可以通过删除其中一个init函数中不需要的参数来解决此问题。

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) 
    } 
} 

}

鉴于这两种方法的签名都是一样的,你不能使用相同的标签不同类型的第二个参数和零,你可以创建一个静态方法的默认值对于你的班级,将采取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")