2017-02-22 183 views
1

我正在尝试使用作为我创建的结构的键和作为Ints数组的值创建字典。但是,我不断收到错误:Type 'dateStruct' does not conform to protocol 'Hashable'。我很确定我已经实施了必要的方法,但由于某种原因,它仍然无法正常工作。这里是我的结构与执行的协议:符合Hashable协议?

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 
       } 
      } 
     } 
    } 
} 

任何人都可以请解释为什么我仍然得到错误?

回答

9

你缺少声明:

struct dateStruct: Hashable { 

BTW - 结构和类名应以大写字母开头。

而你的==功能是错误的。你应该比较这三个属性。

static func == (lhs: dateStruct, rhs: dateStruct) -> Bool { 
    return lhs.year == rhs.year && lhs.month == rhs.month && lhs.day == rhs.day 
} 

有可能两个不同的值具有相同的散列值。

+0

谢谢!顺便说一句,为什么'=='错了?不管是同一天,同一天,同一年的两个日期是否具有相同的hash值? – MarksCode

+0

当然,两个相同的日期将具有相同的散列。但是具有相同散列的两个日期不一定相等。两个不同的日期可以具有相同的散列。没关系。但是具有相同散列的两个日期不必相同。 – rmaddy

+0

嗯我很困惑,无论如何是我的'返回(年+月+日).hashValue'不足够,因为2个不同日期的年份,月份和日期可以加起来相同的东西,如2000,1,2和2000,2, 1? – MarksCode

1

定义结构时,未指定的哈希的协议:struct dateStruct: Hashable {...

下面的代码是从您的例子,它运行在一个游乐场。请注意,您的==运营商已在此处进行修改

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