我是swift的新手,并通过教程了解更多。
在下面的代码中,我定义了自定义运算符(<和==),但是代码运行良好,但Xcode在第一行代码中显示了这些错误。
Type 'SuitedCard' does not conform to protocol 'Equatable'
Type 'SuitedCard' does not conform to protocol 'Comparable'代码如下:
struct SuitedCard: Equatable, Comparable {
// a card can be ♥️, ♣️, ♦️, ♠️
enum Suit {
case hearts
case spades
case diamonds
case clubs
}
// the possible values of a card
enum Value: Int {
case two = 2
case three = 3
case four = 4
case five = 5
case six = 6
case seven = 7
case eight = 8
case nine = 9
case ten = 10
case jack = 11
case queen = 12
case king = 13
case ace = 14
}
// properties
let suit: Suit
let value: Value
var isFaceDown: Bool
}
var valueArray: [SuitedCard.Value] = [.ten, .jack, .queen, .king]
func ==(lhs: SuitedCard, rhs: SuitedCard) -> Bool {
for cardValue in valueArray {
if lhs.value == cardValue {
for cardValue2 in valueArray {
if rhs.value == cardValue2 {
return true
}
}
}
}
if lhs.value == rhs.value {
return true
}
return false
}
func <(lhs: SuitedCard, rhs: SuitedCard) -> Bool {
var lhsRawValue: Int
var rhsRawValue: Int
if lhs.value == .jack || lhs.value == .queen || lhs.value == .king {
lhsRawValue = 10
} else {
lhsRawValue = lhs.value.rawValue
}
if rhs.value == .jack || rhs.value == .queen || rhs.value == .king {
rhsRawValue = 10
} else {
rhsRawValue = rhs.value.rawValue
}
return lhsRawValue < rhsRawValue
}
let smaller = SuitedCard(suit: .hearts, value: .five, isFaceDown: true)
let bigger = SuitedCard(suit: .diamonds, value: .six, isFaceDown: false)
smaller >= smaller
smaller < bigger怎么了?
发布于 2017-01-21 14:56:06
在Swift 3中,协议所需的运算符被声明为静态成员。
使用此类协议的一种方法是将运算符定义作为静态成员移动到结构中:
struct SuitedCard: Comparable { //### Comparable implies Equatable
//...
// function for custom operator ==
static func ==(lhs: SuitedCard, rhs: SuitedCard) -> Bool {
//...
return false
}
// function for custom operator <
static func <(lhs: SuitedCard, rhs: SuitedCard) -> Bool {
//...
return false
}
}另一种方法是,您可以使用扩展来声明与协议的一致性:
struct SuitedCard {
//...
}
// function for custom operator ==
func ==(lhs: SuitedCard, rhs: SuitedCard) -> Bool {
//...
return false
}
// function for custom operator <
func <(lhs: SuitedCard, rhs: SuitedCard) -> Bool {
//...
return false
}
extension SuitedCard: Comparable {}发布于 2017-04-03 14:02:18
OOPer的答案解决了这个问题,但是在Swift 3中,运算符方法也可以在类/结构体之外定义。因此,在本例中,只需将valueArray声明移动到==方法的主体中即可解决问题。以下是更正后的代码:
struct SuitedCard: Equatable, Comparable {
// a card can be ♥️, ♣️, ♦️, ♠️
enum Suit {
case hearts
case spades
case diamonds
case clubs
}
// the possible values of a card
enum Value: Int {
case two = 2
case three = 3
case four = 4
case five = 5
case six = 6
case seven = 7
case eight = 8
case nine = 9
case ten = 10
case jack = 11
case queen = 12
case king = 13
case ace = 14
}
// properties
let suit: Suit
let value: Value
var isFaceDown: Bool
}
func ==(lhs: SuitedCard, rhs: SuitedCard) -> Bool {// valueArray的声明移到这里:
let valueArray: [SuitedCard.Value] = [.ten, .jack, .queen, .king]
for cardValue in valueArray {
if lhs.value == cardValue {
for cardValue2 in valueArray {
if rhs.value == cardValue2 {
return true
}
}
}
}
if lhs.value == rhs.value {
return true
}
return false
}
func <(lhs: SuitedCard, rhs: SuitedCard) -> Bool {
var lhsRawValue: Int
var rhsRawValue: Int
if lhs.value == .jack || lhs.value == .queen || lhs.value == .king {
lhsRawValue = 10
} else {
lhsRawValue = lhs.value.rawValue
}
if rhs.value == .jack || rhs.value == .queen || rhs.value == .king {
rhsRawValue = 10
} else {
rhsRawValue = rhs.value.rawValue
}
return lhsRawValue < rhsRawValue
}
let smaller = SuitedCard(suit: .hearts, value: .five, isFaceDown: true)
let bigger = SuitedCard(suit: .diamonds, value: .six, isFaceDown: false)
smaller >= smaller
smaller < bigger发布于 2020-04-14 21:25:05
Swift 5可等同且可比的协议:
// Car Model
struct Car {
let name: String
let id: Int
let weight: Double
}
// MARK: - Compare if to object are equal if specific parameter(s) are equal.
extension Car: Equatable {
static func == (lhs: Car, rhs: Car) -> Bool {
if lhs.id == rhs.id {
return true
} else {
return false
}
}
}等同的例子
let carsList: [Car] = []
let favouriteCar: Car = Car(name: "Brand", id: 1, weight: 4000)
// Ex. 1
if carsList.contains(favouriteCar) {
print("Favourite car is ready to be delivered!")
}
// Ex. 2
if carsList.first == favouriteCar {
print("Favourite car is first to be delivered!")
}可比协议
// MARK: - Compare to object from specific parameter(s) using the relational operators <, <=, >=, and >.
extension Car: Comparable {
static func < (lhs: Car, rhs: Car) -> Bool {
if lhs.weight < rhs.weight {
return true
} else {
return false
}
}
}可比较的例子
let carsList: [Car] = []
let favouriteCar: Car = Car(name: "Brand", id: 1, weight: 4000)
if carsList.first < favouriteCar {
print("First car in the lighter compare to favourite car!")
} else if carsList.first > favouriteCar {
print("First car in the heavier compare to favourite car!")
} else {
print("First car and favourite car have the same weight!")
}https://stackoverflow.com/questions/41776448
复制相似问题