我正在尝试使用键创建一个字典作为我创建的结构,并将值作为Ints数组。但是,我一直收到错误:struct dateStruct {
var year: Int
var month: Int
var day: Int
var hashValue: Int {
return (year+month+day).hashValue
}
static func == (lhs: dateStruct, rhs: dateStruct) -> Bool {
return lhs.hashValue == rhs.hashValue
}
static func < (lhs: dateStruct, rhs: dateStruct) -> Bool {
if (lhs.year < rhs.year) {
return true
} else if (lhs.year > rhs.year) {
return false
} else {
if (lhs.month < rhs.month) {
return true
} else if (lhs.month > rhs.month) {
return false
} else {
if (lhs.day < rhs.day) {
return true
} else {
return false
}
}
}
}
}
。我很确定我已经实现了必要的方法但由于某种原因它仍然不起作用。这是我的结构与实现的协议:
+--------------+-------------------+---------+----------+--------------------+--------------+------------------+-------------+---------------+----------------+
| name | descr | adminSt | authSt | server_hostname_ip | server_descr | server_preferred | server_EPG | server_minPol | server_maxPoll |
+--------------+-------------------+---------+----------+--------------------+--------------+------------------+-------------+---------------+----------------+
| test1-NTPPOL | Test NTP Policy | enabled | disabled | 10.10.10.10 | NTP1 server | yes | oob-default | 4 | 6 |
+--------------+-------------------+---------+----------+--------------------+--------------+------------------+-------------+---------------+----------------+
| | | | | 10.10.10.11 | NTP2 server | no | oob-default | 4 | 6 |
+--------------+-------------------+---------+----------+--------------------+--------------+------------------+-------------+---------------+----------------+
| | | | | 10.10.10.12 | NTP3 server | no | oob-default | 4 | 6 |
+--------------+-------------------+---------+----------+--------------------+--------------+------------------+-------------+---------------+----------------+
| test2-NTPPOL | Test 2 NTP policy | enabled | disabled | 20.10.10.10 | NTP1 server | yes | oob-default | 4 | 6 |
+--------------+-------------------+---------+----------+--------------------+--------------+------------------+-------------+---------------+----------------+
| | | | | 20.10.10.11 | NTP2 server | no | oob-default | 4 | 6 |
+--------------+-------------------+---------+----------+--------------------+--------------+------------------+-------------+---------------+----------------+
| | | | | 20.10.10.12 | NTP3 server | no | oob-default | 4 | 6 |
+--------------+-------------------+---------+----------+--------------------+--------------+------------------+-------------+---------------+----------------+
有人可以向我解释为什么我仍然会收到错误吗?
答案 0 :(得分:19)
你错过了宣言:
struct dateStruct: Hashable {
BTW - 结构和类名称应以大写字母开头。
您的==
功能错误。你应该比较这三个属性。
static func == (lhs: dateStruct, rhs: dateStruct) -> Bool {
return lhs.year == rhs.year && lhs.month == rhs.month && lhs.day == rhs.day
}
两个不同的值可能具有相同的哈希值。
答案 1 :(得分:3)
顺便说一句
var hashValue: Int
已过时(在旧版NSObject继承树中除外)。
func hash(into hasher: inout Hasher)
{
hasher.combine(year);
hasher.combine(month)
...
是新方法
答案 2 :(得分:2)
如果该类具有类型(另一个类)的字段,则该类应采用 Hashable。
示例
struct Project : Hashable {
var activities: [Activity]?
}
这里,Activity类也必须采用Hashable。
答案 3 :(得分:1)
在定义struct:struct dateStruct: Hashable {...
以下代码来自您的示例,它在Playground上运行。请注意您的==运算符已在此处修改:
import Foundation
struct dateStruct: Hashable {
var year: Int
var month: Int
var day: Int
var hashValue: Int {
return (year+month+day).hashValue
}
static func == (lhs: dateStruct, rhs: dateStruct) -> Bool {
return lhs.year == rhs.year && lhs.month == rhs.month && lhs.day == rhs.day
}
static func < (lhs: dateStruct, rhs: dateStruct) -> Bool {
if (lhs.year < rhs.year) {
return true
} else if (lhs.year > rhs.year) {
return false
} else {
if (lhs.month < rhs.month) {
return true
} else if (lhs.month > rhs.month) {
return false
} else {
if (lhs.day < rhs.day) {
return true
} else {
return false
}
}
}
}
}
var d0 = dateStruct(year: 2017, month: 2, day: 21)
var d1 = dateStruct(year: 2017, month: 2, day: 21)
var dates = [dateStruct:Int]()
dates[d0] = 23
dates[d1] = 49
print(dates)
print(d0 == d1) // true
d0.year = 2018
print(d0 == d1) // false
答案 4 :(得分:1)
如果您不想使用hashValue,可以将值的哈希值与hash(into:)
方法结合使用。
有关更多信息,请参见答案:https://stackoverflow.com/a/55118328/1261547
答案 5 :(得分:0)
对于简单结构,其所有属性已经为Hashable
(即Int
,String
,...),我们可以遵循Hashable
只是声明它(参见https://developer.apple.com/documentation/swift/hashable)
因此无需实现hashValue
(不推荐使用btw)或==
(因为Hashable
符合Equatable
)。
由于我们正在实现<
运算符,因此符合Comparable
是有意义的,因此我们可以进行排序(即[dateStructA, dateStructB, ...].sorted()
)。
所以我会这样做:
struct DateStruct: Comparable & Hashable {
let year: Int
let month: Int
let day: Int
static func < (lhs: DateStruct, rhs: DateStruct) -> Bool {
if lhs.year != rhs.year {
return lhs.year < rhs.year
} else if lhs.month != rhs.month {
return lhs.month < rhs.month
} else {
return lhs.day < rhs.day
}
}
}