Целью было преобразовать элементы из общего списка в словарь для переменной uniqueKeys
, но я увидел ошибку:
Невозможно указать значение неправильного или неоднозначного типа
Я знал что-то необходимое для соответствия протоколу Hashable
и в итоге нашел решение, но не до конца понимаю, почему это решение работает.
- Я понимаю, почему
T
должно быть Hashable
, поскольку оно входит в ключ словаря, но почему также CustomSet
?
- Если
CustomSet
использует Hashable
, почему мне не нужно ничего писать в его расширении?
исходный код
struct CustomSet<T : Comparable > {
private var list: [T]
init(_ list: [T]){
let uniqueKeys = list.reduce(into: [:]){ dict, item in
dict[item, default: 0] += 1
}.keys
self.list = Array(uniqueKeys)
}
}
extension CustomSet : Equatable {
static func == (lhs: CustomSet, rhs: CustomSet) -> Bool {
return lhs.list.count == rhs.list.count && lhs.list.sorted() == rhs.list.sorted()
}
}
Я наконец решил это с помощью:
struct CustomSet<T : Comparable > : Hashable where T : Hashable {
private var list: [T]
init(_ list: [T]){
let uniqueKeys = list.reduce(into: [:]){ dict, item in
dict[item, default: 0] += 1
}.keys
self.list = Array(uniqueKeys)
}
}
extension CustomSet : Equatable {
static func == (lhs: CustomSet, rhs: CustomSet) -> Bool {
return lhs.list.count == rhs.list.count && lhs.list.sorted() == rhs.list.sorted()
}
}
Я также заметил, что с учетом расширения: extension CustomSet: Hashable where T : Hashable
не похоже на struct CustomSet<T : Comparable > : Hashable where T : Hashable
с точки зрения добавления протокола Hashable, потому что я все еще вижу эту ошибку
Что я пробовал
Если я добавлю это к универсальному типу T
, я все еще вижу ту же ошибку.
struct CustomSet<T : Comparable, Hashable >
Если я добавлю Hashable
к CustomSet
, я вижу ошибку
Невозможно преобразовать значение типа '[T]' в ожидаемый тип аргумента.
'UnsafeRawBufferPointer'
и
Наследование от недопустимого типа 'Hashable'
extension CustomSet : Equatable, Hashable {
static func == (lhs: CustomSet, rhs: CustomSet) -> Bool {
return lhs.list.count == rhs.list.count && lhs.list.sorted() == rhs.list.sorted()
}
func hash(into hasher: inout Hasher) {
var hashValue: Int {
var hasher = Hasher()
self.hash(into: &hasher)
return hasher.finalize()
}
}
}