在我提交雷达之前,只需与社区进行健全检查:
在.h Obj-C文件中:
@protocol myProto <NSObject>
@end
Run Code Online (Sandbox Code Playgroud)
在.swift文件中(可通过桥接头访问上述协议定义):
class myClass {
// This line compiles fine
var dictOne: [NSObject:Int]?
// This line fails with "Type 'myProto' does not conform to protocol 'Hashable'"
var dictTwo: [myProto:Int]?
}
Run Code Online (Sandbox Code Playgroud)
NSObject类的检验表明,它(或NSObjectProtocol它映射到)不执行由所述哈希的协议所需的散列值的方法,也没有明确地通过.
所以,在幕后的某个地方,尽管如此,NSObject仍被标记为Hashable,但不会扩展到采用NSObject/NSObjectProtocol的协议.
我有错误或错过了什么吗?
:) Teo
附加信息:
该文件表明:
==.字典键类型的哈希值类型必须是可散列的才能用作字典的键类型 - 也就是说,类型必须提供计算自身散列值的方法.散列值是一个Int值,是对于比较相等的所有对象中,相同的,使得如果一个== B,它遵循a.hashValue == b.hashValue.
所有斯威夫特的基本类型(如字符串,整数,双精度和布尔)的默认情况下可哈希的,而所有这些类型的可以作为一个字典的键.默认情况下,没有关联值的枚举成员值(如枚举中所述)也是可清除的.
注意您可以使用自己的自定义类型作为字典键类型,使其符合Swift标准库中的Hashable协议.符合所述哈希的协议类型必须提供一个gettable int属性称为散列值,并且还必须提供"等于"运算符(==)的实现.类型的hashValue属性返回的值在同一程序的不同执行或不同程序中不需要相同.有关符合协议的更多信息,请参阅协议.
我在Swift中有一个结构,如下所示:
internal struct MapKey {
internal let id: String
internal let values: [String:String]
}
extension MapKey: Equatable {}
func ==(lhs: MapKey, rhs: MapKey) -> Bool {
return lhs.id == rhs.id && lhs.values == rhs.values
}
Run Code Online (Sandbox Code Playgroud)
我现在需要使用MapKey作为Swift字典中的键,这需要MapKey符合Hashable协议.
对于像这样的结构,Hashable的正确实现是什么?
extension MapKey: Hashable {
var hashValue: Int {
return ??? // values does not have a hash function/property.
}
}
Run Code Online (Sandbox Code Playgroud)
我一直在做一些研究,但未能确定散列字典的正确方法是什么,因为我需要能够为values属性本身生成散列值.任何帮助深表感谢.
I'm going around in circles trying to get Hashable to work with multiple struct that conform to the same protocol.
I have a protocol SomeLocation declared like this:
protocol SomeLocation {
var name:String { get }
var coordinates:Coordinate { get }
}
Run Code Online (Sandbox Code Playgroud)
Then I create multiple objects that contain similar data like this:
struct ShopLocation: SomeLocation, Decodable {
var name: String
var coordinates: Coordinate
init(from decoder: Decoder) throws {
...
}
}
struct CarLocation: SomeLocation, Decodable {
var name: …Run Code Online (Sandbox Code Playgroud) 我刚碰到了一些有趣的东西,我以为我会问.
将字典添加到a中set,我假设字典将被添加为完整字典,但事实并非如此.只添加了键:
dicty = {"Key1": "Val1", "Key2": "Val2"}
setunion = set()
setunion.union(dicty)
=> set(['Key2', 'Key1'])
Run Code Online (Sandbox Code Playgroud)
当您尝试使用它添加它时,set.add()您会收到错误:
setadd = set()
setadd.add(dicty)
Traceback (most recent call last):
File "python", line 1, in <module>
TypeError: unhashable type: 'dict'
Run Code Online (Sandbox Code Playgroud)
显然,这种行为与列表非常不同:
listy = []
listy.append(dicty)
listy
=> [{'Key2': 'Val2', 'Key1': 'Val1'}]
Run Code Online (Sandbox Code Playgroud)
在文档中,它表示集合是可散列对象的无序集合,这是对上述某些问题的暗示.
这里发生了什么?设置项目必须是可清洗的,所以很清楚,这与为什么我只是将键添加到设置中.union(),但为什么错误与.add()?
列表中集合的行为差异背后是否有一些可用性原因?
Python(或库)中是否存在基本上像列表一样的数据类型,但只保留唯一项?
我试图理解Python字典必须在内部做什么才能找到密钥.在我看来,哈希将首先被评估,如果有冲突,Python将遍历键,直到找到一个eq返回True的那个.这让我想知道为什么以下代码有效(测试代码仅用于理解内部):
class MyClass(object):
def __eq__(self, other):
return False
def __hash__(self):
return 42
if __name__=='__main__':
o1 = MyClass()
o2 = MyClass()
d = {o1: 'o1', o2: 'o2'}
assert(o1 in d) # 1
assert(d[o1]=='o1') # 2
assert(o2 in d) # 3
assert(d[o2]=='o2') # 4
Run Code Online (Sandbox Code Playgroud)
字典不应该无法找到正确的密钥(在#2和#4情况下返回'o1'或'o2',或者抛出错误,具体取决于内部实现).在两种情况下,当它永远不能正确地"等同"键时(因为eq返回False),它如何能够在正确的键上着陆.
我在哈希上看到的所有文档总是提到哈希和eq,而不是cmp,ne等,这让我觉得这两个是唯一在这个场景中发挥作用的人.
我正在使用sqlite文件从authorId获取diaryEntriesTeacher。当我打印变量authorId为nil时,它会生成authorId的以下对象:-
func applySelectQuery() {
checkDataBaseFile()
objFMDB = FMDatabase(path: fullPathOfDB)
objFMDB.open()
objFMDB.beginTransaction()
do {
let results = try objFMDB.executeQuery("select * from diaryEntriesTeacher", values: nil)
while results.next() {
let totalCount = results.resultDictionary
let authorId = totalCount?["authorId"]!
print("authorId",authorId)
}
}
catch {
print(error.localizedDescription)
}
print(fullPathOfDB)
self.objFMDB.commit()
self.objFMDB.close()
}
Run Code Online (Sandbox Code Playgroud)
我想创建一组在我的应用程序中使用的 gorm 类型。所以我想map用我的类型定义 agorm.DB作为键,空structs{}作为标志:
var (
autoMigrations map[gorm.DB]struct{}
)
Run Code Online (Sandbox Code Playgroud)
但是编译器不允许我用错误来做这个:invalid map key type gorm.DB. 我可以使用指向gorm.DBs 的指针来愚弄它,例如:
map[*gorm.DB]struct{}
Run Code Online (Sandbox Code Playgroud)
但这不是解决方案,因为我需要使它独一无二,如果我的地图被填满,db.AutoMigrate(&Chat{})我可以获得许多具有不同地址的类似对象。
另一种解决方案是制作一片gorm.DB:
autoMigrations []gorm.DB
Run Code Online (Sandbox Code Playgroud)
但是我必须手动过滤元素,这似乎有点疯狂。
在处理哈希映射时,我已经看到了一些处理哈希冲突的策略,但我们提出了一些不同的东西.我想知道这是否是新事物.
只有散列和将要散列的数据结构可以使用时,此版本的散列映射才有效.(hashable在Haskell中就是这种情况,我们建议实现这种方法.)
我们的想法是,不是在哈希映射的每个单元格中存储列表或数组,而是存储递归哈希映射.这个递归哈希映射的唯一区别是你使用不同的盐.这样,哈希映射的一个级别上的哈希冲突很可能不是下一级别的哈希冲突.因此,插入这样的哈希映射不再是O(此哈希上的冲突数),而是O(这种冲突在递归时发生的级别数),这很可能更好.
可以在此处找到更详细的说明和实现:
在Apple 文档中NSXPCInterface.setClasses(_:for:argumentIndex:ofReply:),对于 Swift,第一个参数描述为:
包含 Class 对象 \xe2\x80\x94 的 NSSet,例如 [MyObject class]。
\n\n嗯,看起来好像有人忽略了将其从 Objective-C 更新到 Swift。对于 Swift 我认为它应该是这样的
\n\n包含类类型的集合
\n\n(请有人纠正我的措辞。)但是如何制作包含类类型的 Set 呢? 编译器不允许我声明Set其成员类型不符合的成员Hashable。这是有道理的,因为需要哈希来保持成员之间的唯一性。但 Swift 中的类类型似乎不可散列。在任何 Swift 文件或游乐场\xe2\x80\xa6 中尝试此操作
class Foo {}\nlet mySet: Set<AnyHashable>\nmySet.insert(Foo)\nRun Code Online (Sandbox Code Playgroud)\n\n编译器抱怨:
\n\n参数类型“Foo.Type”不符合预期类型“Hashable”
\n\n或者,更广泛地说,有人知道如何NSXPCInterface.setClasses(_:for:argumentIndex:ofReply:)在 Swift 5 中使用吗?
我有这样的看法:
import SwiftUI
struct SectionView1: View {
let dateStr:String
@Binding var isSectionView:Bool
var body: some View {
HStack {
Button(action: {
self.isSectionView.toggle()
}) {
Image(systemName: isSectionView ? "chevron.down.circle" : "chevron.right.circle")
}
Text("Media del \(dateStr)")
}
}
}
Run Code Online (Sandbox Code Playgroud)
将从视图中调用:
import SwiftUI
import Photos
struct MediaView: View {
let geoFolder:GeoFolderCD
@State private var assetsForDate = [String :[PHAsset]]()
@State private var isSectionViewArray:[String:Bool] = [:]
var body: some View {
List {
ForEach(assetsForDate.keys.sorted(by: > ), id: \.self) { dateStr in
Section {
SectionView1(dateStr: dateStr, …Run Code Online (Sandbox Code Playgroud)