我想这样做...
let myInt = E.i(420)
let myString = E.s("Crook")
。有了这个...
enum E {
case i(Int?)
case s(String?)
func i() -> Int? {
// How do I implement?
}
func s() -> String? {
// How do I implement?
}
}
。所以我可以这样做...
let theInt = myInt.i()
let theString = myDouble.s()
。或者更好的是,这样做...
let betterInt = myInt.i
let betterString = myString.s
。或者如果我想在天堂...
let i = myInt // based on associated value return typed value as Int or nil
let i: Int = myInt // convert it automatically and return Int or nil
let s = myString // based on associated value return typed value as String or nil
let s: String = myString // convert it automatically and return String or nil
你可以做这样的事情:
enum E {
case i(Int?)
case s(String?)
var i: Int? {
switch self {
case .i(let value): return value
case .s(_): return nil
}
}
var s: String? {
switch self {
case .i(_): return nil
case .s(let value): return value
}
}
}
可悲的是,你的天堂解决方案并不完全可行。您必须重载=
运算符,这在 Swift(Apple 文档(中是禁止的。
我不确定您要执行的操作与类型转换有何不同。
如果您有:
let myInt = 420
let myString = "Crook"
然后
let i = myInt as? Int // makes i an Int? which would be nil if myInt didn't
// actually contain an integer
// note that a non-optional Int would not accept a nil
// so heaven cannot work as you would expect
let s = mySting as? String // makes s a String? ...
您声明为 E(...( 的变量只需要声明为 Any。
如果需要特定的类型子集,可以为它们定义一个协议,并使用它而不是 Any。
例如:
protocol E
{}
extension Int:E {}
extension String:E {}
let myVariable:E = 3
let i = myVariable as? Int
您还可以扩展语法糖果的协议:
extension E
{
var value:Int? { return self as? Int }
}
let i:Int? = myVariable.value
感谢Cabus!!我稍微改变了它,以避免机箱上的凌乱开关
不确定这是否适用于泛型。我没有尝试,因为我想限制类型,并且没有看到将显式限制为我需要的类型的方法。
它也不是完美的,因为我必须在使用 Int32 和 Double 时明确通知编译器。指定"类型化"nil
很笨拙。但是我可以忍受。
public enum D {
case Int (Int32?)
case Double (Double?)
case String (String?)
public init(_ i: Int32?) {
self = .Int(i)
}
public init(_ d: Double?) {
self = .Double(d)
}
public init(_ s: String?) {
self = .String(s)
}
var int: Int32? {
if case D.Int(let int) = self { return int }
return nil
}
var double: Double? {
if case D.Double(let double) = self { return double }
return nil
}
var string: String? {
if case D.String(let string) = self { return string }
return nil
}
}
测试代码...
let myInt = D(Int32(2))
let myString = D("Two")
let myDouble = D(Double(2.0))
let myIntOptional = D.Int(nil) // when wanting to use "typed" nil
print("myInt = (myInt.int)")
print("myString = (myString.string)")
print("myDouble = (myDouble.double)")
print("myIntOptional = (myIntOptional.int)")
感谢任何改进建议。
这是我使用泛型的解决方案。
public enum E<T> {
case Value (T)
public init (_ t: T) {
self = .Value(t)
}
var value: T {
switch self {
case .Value(let t): return t
}
}
}
测试代码...
let myInt = E<Int32>(2)
let myString = E<String>("Two")
let myDouble = E<Double>(2)
let myDate = E<Date>(Date())
let myIntOptional = E<Int32?>(nil)
let myIntOptionalWithValue = E<Int32?>(4444)
print("myInt = (myInt.value)")
print("myString = (myString.value)")
print("myDouble = (myDouble.value)")
print("myDate= (myDate.value)")
print("myIntOptional = (myIntOptional.value)")
print("myIntOptionalWithValue = (myIntOptionalWithValue.value)")
测试结果...
myInt = 2
myString = Two
myDouble = 2.0
myDate= 2018-02-05 02:52:51 +0000
myIntOptional = nil
myIntOptionalWithValue = Optional(4444)
恕我直言,它现在不那么混乱,更具可读性,并且可以满足您的需求。