AnyObject尝试转换为Equatable
我有一个Equatable
类AnyObject尝试转换为Equatable
class Item: Equatable {
var value: AnyObject?
var title: String
init(title: String, value: AnyObject?) {
self.title = title
self.value = value
}
//Equatable
public static func ==(lhs: Item, rhs: Item) -> Bool {
return ((lhs.title == rhs.title) && (lhs.value === rhs.value))
}
}
但我想投试无功value
到Equatable,这样拿到手软equatable结果
if let lValue = lhs.value as? Equatable, // Error
let rValue = rhs.value as? Equatable { // Error
valueEq = (lValue == rValue)
} else {
valueEq = (lhs.value === rhs.value)
}
此代码捕获编译错误关于通用Equatable
我怎么样我可以做正确的对于这个班的Equatable?
UPD
我想用我的Item
在UITableViewCell
在我的故事板。我不能创建通用的UITableViewCell
。如果我尝试做的项目为Generic<T: Equatable>
类,我将不得不在我的细胞对指定类型,
var items: [Item<OnlyThisHashableClass>]
但我想使用细胞项目的任何对象
简单的方法 - 类留非泛型,通用只有init
,并在GenericInit创建isEquals方法
class FieldItem: CustomStringConvertible, Equatable {
let value: Any?
let title: String
private let equals: (Any?) -> Bool
init<Value: Equatable>(title: String, value: Value?) {
func isEquals(_ other: Any?) -> Bool {
if let l = value, let r = other {
if let r = r as? Value {
return l == r
} else {
return false
}
} else {
return true
}
}
self.title = title
self.value = value
self.equals = isEquals
}
//CustomStringConvertible
var description: String { get { return title } }
//Equatable
public static func ==(lhs: FieldItem, rhs: FieldItem) -> Bool {
return ((lhs.title == rhs.title) && lhs.equals(rhs.value))
}
}
你可以不投AnyObject
到一个Equatable
。
你可以做的是定义Item
作为通用为其value
,Wrapped
,必须Equatable
:
class Item<Wrapped: Equatable> {
var title: String
var value: Wrapped
init(title: String, value: Wrapped) {
self.title = title
self.value = value
}
}
extension Item: Equatable {
static func ==(lhs: Item, rhs: Item) -> Bool {
return lhs.title == rhs.title && lhs.value == rhs.value
}
}
而且,让我们假设你有一些类,Foo
,即(一)ISN”可以等同的; (b)是你想包装在Item
;和(c)你真的想要在身份运算符===
的基础上将它们定义为equatable。 (我承认,我发现这个概念,你称之为“软等于”相当令人不安的概念,但我不会在这里进入这一点。)
无论如何,你可以使你的类Foo
equatable的基础上身份操作:
extension Foo: Equatable {
static func ==(lhs: Foo, rhs: Foo) -> Bool {
return lhs === rhs
}
}
或者,如果你需要为很多类做到这一点,你甚至可以为这个身份平等的协议,然后你的非equatable类可能只是符合是:
protocol IdentityEquatable: class, Equatable { }
extension IdentityEquatable {
static func ==(lhs: Self, rhs: Self) -> Bool {
return lhs === rhs
}
}
然后,你想要wr的任何类AP在Item
未Equatable
可以采取与每个代码一行这个身份equatable行为:
extension Foo: IdentityEquatable { }
extension Bar: IdentityEquatable { }
extension Baz: IdentityEquatable { }
顺便说一句,SE-0143已获批准,而不是语言的一部分,但,提供条件一致性的未来斯威夫特版本的承诺,即:
class Item<Wrapped> {
var title: String
var value: Wrapped
init(title: String, value: Wrapped) {
self.title = title
self.value = value
}
}
extension Item: Equatable where Wrapped: Equatable {
static func ==(lhs: Item, rhs: Item) -> Bool {
return lhs.title == rhs.title && lhs.value == rhs.value
}
}
在这种情况下,Item
将Equatable
当且仅当该Wrapped
VAL你是Equatable
。这不是该语言的一部分,但看起来像将在未来的版本。这是一个优雅的解决方案(虽然不是,不可否认,你的“软等值”思想)。
但我在许多类中使用我的'Item',例如在故事板中的'UITableViewCell'中。如果我尝试将'Item'作为Generic类,我将*指定单元格中的类型,但是我希望使用Cells中的Item作为基类(值 - AnyObject) –
你的代码为您发布什么问题? – rmaddy
您需要创建一个符合Equatable的自定义值类型。 –
用确切完整的错误信息更新您的问题,而不是一些总结。 – rmaddy