我正在尝试创建一个类,并将该类用作我的新枚举的类型,如下所示。
class Abc{
var age = 25
var name = "Abhi"
}
enum TestEnum : Abc {
case firstCase
case secondCase
}
我在操场上遇到以下错误。
error: raw type 'Abc' is not expressible by any literal
所以我尝试遵循这样的RawRepresentable协议。
extension TestEnum : RawRepresentable{
typealias RawValue = Abc
init?(rawValue:RawValue ) {
switch rawValue {
case Abc.age :
self = .firstCase
case Abc.name :
self = .secondCase
}
}
var rawValue : RawValue {
switch self{
case .firstCase :
return Abc.age
case .secondCase :
return Abc.name
}
}
}
我在此之后遇到以下错误:
error: raw type 'Abc' is not expressible by any literal
error: instance member 'age' cannot be used on type 'Abc'
error: instance member 'name' cannot be used on type 'Abc'
声明某个类类型的枚举的正确方法是什么,而不是对此有明确的想法。有人帮忙吗?
答案 0 :(得分:12)
来自文档
特别是,原始值类型必须符合Equatable 协议和以下协议之一: ExpressibleByIntegerLiteral用于整数文字, 用于浮点文字的ExpressibleByFloatLiteral, 包含任意数字的字符串文字的ExpressibleByStringLiteral 字符和ExpressibleByUnicodeScalarLiteral或 ExpressibleByExtendedGraphemeClusterLiteral用于字符串文字 只包含一个字符。
因此,让您的类Abc符合Equatable和上述协议之一。这是一个例子
public class Abc : Equatable,ExpressibleByStringLiteral{
var age = 25
var name = "Abhi"
public static func == (lhs: Abc, rhs: Abc) -> Bool {
return (lhs.age == rhs.age && lhs.name == rhs.name)
}
public required init(stringLiteral value: String) {
let components = value.components(separatedBy: ",")
if components.count == 2 {
self.name = components[0]
if let age = Int(components[1]) {
self.age = age
}
}
}
public required convenience init(unicodeScalarLiteral value: String) {
self.init(stringLiteral: value)
}
public required convenience init(extendedGraphemeClusterLiteral value: String) {
self.init(stringLiteral: value)
}
}
enum TestEnum : Abc {
case firstCase = "Jack,29"
case secondCase = "Jill,26"
}
现在您可以初始化您的枚举
let exEnum = TestEnum.firstCase
print(exEnum.rawValue.name) // prints Jack
有关详细讨论和示例,请参阅 https://swiftwithsadiq.wordpress.com/2017/08/21/custom-types-as-raw-value-for-enum-in-swift/
答案 1 :(得分:10)
我不确定你想要达到什么目的,但请看一下我在项目中使用的实现方法:
class Abc {
var age: Int
var name: String
init(age: Int, name: String) {
self.age = age
self.name = name
}
}
enum TestEnum {
case firstCase
case secondCase
var instance: Abc {
switch self {
case .firstCase: return Abc(age: 25, name: "John")
case .secondCase: return Abc(age: 20, name: "Marry")
}
}
}
//Usage:
let abc = TestEnum.secondCase.instance
print(abc.age) //prints '20'
答案 2 :(得分:2)
看看Associated Values。 以你的例子:
class Abc {
var age = 25
var name = "Abhi"
}
enum TestEnum {
case age(Int)
case name(String)
}
然后你可以像这样使用它:
var person = Abc()
...
var value = TestEnum.age(person.age)
switch value {
case .age(let age):
print("Age: \(age).")
case .name(let name):
print("Name: \(name).")
}
为方便起见,您可以为枚举编写扩展名,这将使您的Abc
对象转换为枚举值:
static func fromAbc(_ object: Abc) -> TestEnum? {
if object.age {
return TestEnum.age(object.age)
}
if object.name {
return TestEnum.name(object.name)
}
return nil
}
注意:在func fromAbc(object: Abc) -> TestEnum?
中,您应该将if中的条件替换为可以表示为Bool(age > 0
等)的条件。
至于行值 - 在doc中声明
原始值可以是字符串,字符或任何整数或浮点数类型。每个原始值在其枚举声明中必须是唯一的。
而且我不确定你能在那里上课。