如何在GLib哈希表中使用long类型作为键?对应函数选型
如何在GLib哈希表中使用long类型作为键?
这个问题其实挺常见的,核心在于GLib提供的哈希/比较函数是和明确的整数宽度绑定的,而long的大小在不同平台上是可变的——32位系统上它是32位(和int同宽),64位系统上则是64位(和int64_t同宽)。结合你给出的GLib函数选项,这里给你明确的选择方案:
核心选择逻辑
- 如果你需要跨平台兼容性,或者你的代码会运行在64位系统上,直接选用
g_int64_hash()作为哈希函数,g_int64_equal()作为键比较函数。
原因很简单:即使在32位系统上,把long转换成64位的gint64也不会丢失任何数据,这样你的代码在所有平台上都能稳定工作。 - 如果你只在32位平台运行,用
g_int_hash()和g_int_equal()也能工作,但这种写法不具备跨平台性,不推荐。
代码示例(值为自定义结构体指针)
假设你有一个自定义结构体:
typedef struct { int id; char *name; } UserData;
1. 创建哈希表
// 用g_int64_hash和g_int64_equal保证跨平台安全 GHashTable *user_table = g_hash_table_new_full( g_int64_hash, // 哈希函数 g_int64_equal, // 键比较函数 NULL, // 键不需要销毁(因为是基本类型转换的指针) (GDestroyNotify)user_data_destroy // 值的销毁函数 );
2. 自定义结构体的销毁函数
如果需要在哈希表销毁时自动释放结构体内存,实现一个销毁函数:
void user_data_destroy(gpointer data) { UserData *user = (UserData *)data; g_free(user->name); // 释放字符串 g_free(user); // 释放结构体本身 }
3. 插入键值对
注意要把long类型的键转换成gint64,再用GINT_TO_POINTER()包装成指针(GLib哈希表的键/值都是指针类型):
long user_id = 1001; UserData *new_user = g_new(UserData, 1); new_user->id = user_id; new_user->name = g_strdup("Alice"); // 插入哈希表 g_hash_table_insert(user_table, GINT_TO_POINTER((gint64)user_id), new_user);
4. 查找键对应的结构体
同样需要把查找的long键转换成gint64:
long search_id = 1001; UserData *found_user = g_hash_table_lookup(user_table, GINT_TO_POINTER((gint64)search_id)); if (found_user != NULL) { g_print("Found user: %s (ID: %d)\n", found_user->name, found_user->id); }
5. 销毁哈希表
当不再需要哈希表时,调用g_hash_table_destroy()会自动触发所有值的销毁函数:
g_hash_table_destroy(user_table);
额外提醒:别用g_direct_hash/g_direct_equal
g_direct_hash()和g_direct_equal()是用来处理指针本身作为键的场景,不是用来处理整数的。虽然在某些平台上把long转指针可能能运行,但这是未定义行为,绝对不能这么用。
内容的提问来源于stack exchange,提问作者Eren Rust
相关产品推荐
相关产品推荐

