web-dev-qa-db-ja.com

Hashableプロトコルに準拠していますか?

私が作成した構造体としてのキーとIntの配列としての値を使用して辞書を作成しようとしています。ただし、エラーが発生し続けます。

タイプ「DateStruct」はプロトコル「ハッシュ可能」に準拠していません

私は必要なメソッドを実装したと確信していますが、何らかの理由でまだ機能しません。

実装されたプロトコルを使用した構造体は次のとおりです。

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

まだエラーが発生する理由を誰かに説明してもらえますか?

10
MarksCode

宣言がありません:

struct DateStruct: Hashable {

そしてあなたの ==関数が間違っています。 3つのプロパティを比較する必要があります。

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

2つの異なる値が同じハッシュ値を持つ可能性があります。

23
rmaddy

HashValueを使用したくない場合は、値のハッシュをhash(into:)メソッドと組み合わせることができます。

詳細については、回答を参照してください: https://stackoverflow.com/a/55118328/1261547

4
Lilo

構造体を定義するときにHashableプロトコルを指定しませんでした:

struct DateStruct: Hashable { ...

次のコードはあなたの例からのものであり、プレイグラウンドで実行されます。 your ==演算子はここで変更されています

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
1
nbloqs