Skip to content

Commit 517c4eb

Browse files
committed
fix links
1 parent aa17e5c commit 517c4eb

2 files changed

Lines changed: 11 additions & 15 deletions

File tree

content/post/2024-06-10-zig-hashmap-1.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@ author: Wenxuan Feng
44
date: 2024-06-10T07:57:05.138Z
55
---
66

7-
> 原文地址: https://www.openmymind.net/Zigs-HashMap-Part-1/
8-
9-
# 引言
10-
117
> 阅读这篇文章的前提是了解 [Zig 的范型实现](https://www.openmymind.net/learning_zig/generics/)
128
139
如大多数哈希映射实现一样,Zig 的 `std.HashMap` 依赖于两个函数:`hash(key: K) u64``eql(key_a: K, key_b: K) bool`。其中,哈希函数接收一个键并返回一个无符号的64位整数作为哈希码。相同的关键字总是会返回相同的哈希码。然而,为了处理不同的键可能生成相同哈希码的情况(即碰撞),我们还需要 `eql` 函数来确定两个键是否相等。
@@ -384,3 +380,5 @@ pub fn hash(_: HashContext, u: User) u64 {
384380
希望你现在对 Zig 的哈希表的实现以及如何在代码中利用它们有了更好的理解。在大多数情况下,`std.StringHashMap``std.AutoHashMap` 就足够了。但知道 `*Unmanaged` 变体的存在和目的,以及更通用的 `std.HashMap`,可能会派上用场。如果没有其他用途,现在文档和它们的实现应该更容易理解了。
385381

386382
在下一部分,我们将深入探讨哈希表的键和值,它们是如何存储和管理的。
383+
384+
> 原文地址: https://www.openmymind.net/Zigs-HashMap-Part-1/
Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
---
2-
title: "Zig HashMap - 2"
2+
title: "HashMap 原理介绍下篇"
33
author: Wenxuan Feng
4-
date: 2024-06-10T07:57:05.138Z
4+
date: 2024-06-11T07:57:06.138Z
55
---
66

7-
> 原文地址: https://www.openmymind.net/Zigs-HashMap-Part-2/
8-
9-
# 正文
10-
11-
[第一部分](https://www.openmymind.net/Zigs-HashMap-Part-1/)中,我们探讨了六种 `HashMap` 变体之间的关系以及每种变体为开发人员提供的不同功能。我们主要关注如何为各种数据类型定义和初始化 `HashMap`,并讨论了当 `StringHashMap``AutoHashMap` 不支持的类型时使用自定义 `hash``eql` 函数的重要性。在这篇文章中,我们将更深入地研究键和值的存储、访问方式以及我们在它们生命周期管理中的责任。
7+
[第一部分](/post/2024/06/10/zig-hashmap-1/)中,我们探讨了六种 `HashMap` 变体之间的关系以及每种变体为开发人员提供的不同功能。我们主要关注如何为各种数据类型定义和初始化 `HashMap`,并讨论了当 `StringHashMap``AutoHashMap` 不支持的类型时使用自定义 `hash``eql` 函数的重要性。在这篇文章中,我们将更深入地研究键和值的存储、访问方式以及我们在它们生命周期管理中的责任。
128

139
Zig 的哈希表内部采用两个切片结构:一个用于存放键(key),另一个用于存储对应的值(value)。通过应用哈希函数计算得到的哈希码被用来在这些数组中定位条目。从基础代码出发,比如:
1410

@@ -43,7 +39,7 @@ keys: values:
4339

4440
这个基本的可视化表示将贯穿本文大部分内容,并且不断强调条目的位置需要保持一致性和可预测性。即使哈希表需要在增长时从一个底层数组移动到另一个(即当填充因子达到一定阈值并要求扩大以容纳更多数据时),这一事实是我们将反复回顾的主题。
4541

46-
## 值管理
42+
# 值管理
4743

4844
如果我们对上述代码片段进行扩展,并调用 `lookup.get("Paul")`,返回的值将是 `1234`。在处理像 `i32` 这样的原始类型时,很难直观地理解 `get` 方法和它的可选返回类型 `?i32` 或更通用的 `?V`(其中 `V` 表示任何值类型)之间的区别。考虑到这一点,让我们通过替换 `i32` 为一个封装了更多信息的 `User` 类型来展示这一概念:
4945

@@ -224,7 +220,7 @@ while (it.next()) |value_ptr| {
224220

225221
在最后一种情况下,由于我们存储的是 `User` 而不是 `*User`,我们的 `value_ptr` 是指向 `User` 的指针(不像之前那样是指向指针的指针)。
226222

227-
## Keys
223+
# Keys
228224

229225
我们可以开始和结束这一节:我们关于值的所有内容同样适用于键。这是100%正确的,但这在某种程度上不太直观。大多数开发人员很快就能理解,存储在哈希表中的堆分配的 `User` 实例有其自身的生命周期,需要显式管理/释放。但由于某些原因,这对于键来说并不那么明显。
230226

@@ -337,7 +333,7 @@ if (lookup.fetchRemove(user.name)) |kv| {
337333

338334
对于大多数情况,在处理非原始键或值时,关键是当你调用哈希表的 `deinit` 时,你为键和值分配的任何内存不会被自动释放;你需要自己处理。
339335

340-
## getOrPut
336+
# getOrPut
341337

342338
虽然我们已经讨论过的内容有很多含义,但对我来说,直接暴露键和值指针的最大好处之一是 `getOrPut` 方法。
343339

@@ -367,6 +363,8 @@ if (gop.found_existing) {
367363

368364
当然,只要不对哈希表进行修改,`value_ptr` 就应被视为有效。顺便提一句,这同样适用于我们通过 `iterator()``valueIterator``keyIterator` 获取的迭代键和值,原因相同。
369365

370-
## 结论
366+
# 结论
371367

372368
希望你现在对使用「std.HashMap」、「std.AutoHashMap」和「std.StringHashMap」以及它们的「unmanaged」变体感到更加得心应手。虽然你可能永远不需要提供自己的上下文(例如「hash」和「eql」函数),但了解这是一个选项是有益的。在日常编程中,可视化数据尤其有用,尤其是在使用指针和添加间接层次时。每当我处理 `value_ptr``key_ptr` 时,我都会想到这些切片以及值或键与这些切片中值或键的实际地址之间的区别。
369+
370+
> 原文地址: https://www.openmymind.net/Zigs-HashMap-Part-2/

0 commit comments

Comments
 (0)