如何在C语言中实现TypeScript Record类型等效结构并支持运行时动态添加属性
C语言实现TypeScript Record等效结构的方案
C语言本身没有内置的字典/Record类型结构,要实现你要的运行时动态增删键、O(1)时间复杂度字符串键查询、支持任意类型值映射的能力,最通用的方案是使用哈希表(散列表)实现,完全可以避免全数组遍历的性能损耗。
你可以选择直接引入成熟的轻量开源哈希表实现(无额外依赖,稳定性更高),也可以根据业务需求自行实现哈希表逻辑。
最简生产可用实现(基于uthash)
uthash是纯C实现的头文件哈希表库,只需要把uthash.h放到你的项目目录下即可直接引用,不需要额外编译配置。以下代码完全复现你给出的TypeScript示例逻辑:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <stdbool.h> #include "uthash.h" // 定义对应Record<string, boolean>的哈希表结构 typedef struct { char name[20]; // 字符串键,长度可根据实际需求调整 bool exists; // 布尔值 UT_hash_handle hh; // uthash required 固定字段,无需修改 } FamilyHash; int main() { FamilyHash *family = NULL; // 哈希表初始为空 const char *family_data[] = {"paul", "em", "matthias", "kevin"}; int data_len = sizeof(family_data) / sizeof(family_data[0]); // 批量插入数据,等效于TS的forEach赋值逻辑 for (int i = 0; i < data_len; i++) { FamilyHash *item; // 先查重避免重复插入 HASH_FIND_STR(family, family_data[i], item); if (item == NULL) { item = (FamilyHash *)malloc(sizeof(FamilyHash)); strcpy(item->name, family_data[i]); item->exists = true; HASH_ADD_STR(family, name, item); } } // 查询逻辑 const char *query_name = "kevin"; FamilyHash *query_result; HASH_FIND_STR(family, query_name, query_result); if (query_result != NULL) { printf("%d\n", query_result->exists); // 键存在,输出1对应true } else { printf("undefined\n"); // 键不存在输出undefined } // 使用完释放内存避免泄漏 FamilyHash *tmp, *current; HASH_ITER(hh, family, current, tmp) { HASH_DEL(family, current); free(current); } return 0; }
扩展为支持任意类型值的方法
只需要修改哈希表结构体的字段,即可实现通用的任意类型映射Record:
typedef struct { char key[64]; void *value; // 指向任意类型数据的指针 int value_type; // 自定义枚举标记值类型:1=布尔、2=整数、3=自定义结构体等 UT_hash_handle hh; } UniversalRecord;
插入数据时将自定义数据的指针赋值给value字段,查询时根据value_type做对应类型的强制转换即可使用。
从零实现哈希表的核心逻辑(不引入第三方代码)
如果你的场景不允许引入第三方代码,可以自行实现哈希表,核心需要实现三个模块:
- 字符串哈希函数:推荐用BKDR、MurmurHash等成熟算法,将任意字符串映射为整数下标,降低冲突概率
- 哈希冲突处理:通用方案是链地址法,每个哈希下标对应一个短链表,冲突的键存在对应链表中,查询时仅需遍历该短链表,性能远高于全数组遍历
- 动态扩容逻辑:当负载因子(已存键数/哈希数组长度)超过0.7左右时,申请更大的数组,将所有键重新哈希到新数组,进一步降低冲突率
内容的提问来源于stack exchange,提问作者Thibaud
相关产品推荐
相关产品推荐

