我想这样做......
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
答案 0 :(得分:1)
你可以这样做:
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 Documentation)中禁止此操作。
答案 1 :(得分:0)
我不确定你要做的是什么与类型演员不同。
如果你有:
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
答案 2 :(得分:-1)
感谢Cabus !!!我稍微改了一下,以免乱开案件
不确定这适用于Generics。我没有尝试,因为我想限制类型,并没有看到明确限制我需要的类型的方法。
它也不完美,因为我必须在使用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)")
欣赏任何改进建议。
答案 3 :(得分:-1)
所以这是我使用Generics的解决方案。
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)
恕我直言,它现在不那么凌乱,更具可读性,能够满足我的需求。