You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:24:30