使用napi实现ts枚举类型

news/2024/10/6 3:57:35/文章来源:https://www.cnblogs.com/milkpotatoes/p/18286305

在napi模块中定义枚举类型

枚举类型不是js的原生类型,它是ts中独有的语法,但是napi方法仅支持操作js对象。

下文将提供一个demo用来实现一个js的enum类。

分析ts枚举类的实现方式

定义一个ts枚举类

TypeScript 代码如下:

enum EnumClass {VAL_A = 0,VAL_B,VAL_C,
}

使用tsc命令将ts文件转为js文件,生成的js文件内容如下:

var EnumClass;
(function (EnumClass) {EnumClass[EnumClass["VAL_A"] = 0] = "VAL_A";EnumClass[EnumClass["VAL_B"] = 1] = "VAL_B";EnumClass[EnumClass["VAL_C"] = 2] = "VAL_C";
})(EnumClass || (EnumClass = {}));

分析代码,tsc 转换后的代码逻辑如下:

  1. 定义一个全局变量 EnumClass
  2. 构造一个匿名函数,该函数接受一个入参,入参类型经推断应为Object。函数逻辑如下:
    1. 为Object EnumClass定义了三个 keyenum的keyvalueenum的value 的属性。
    2. 为Object EnumClass定义了三个 valueenum的keykeyenum的value 的属性。
  3. 将全局变量EnumClass传递到上述函数,若全局变量EnumClass为undefined或null等值(即或语句前条件为false)则使其为空Object。

根据以上步骤,不难发现,enum在js中实际上是一个key、value互相作为key/value的Object。

使用napi方法进行实现js枚举类

定义一个C/C++的枚举类,其将作为js枚举类在Native枚举类的映射

enum EnumClass { VAL_A = 0,VAL_B,VAL_C,
};

创建一个js Object, 用以容纳枚举类的内容

napi_value enumObject = nullptr;
napi_create_object(env, &enumObject);

定义两个下文将会使用到的宏,减少模板代码

// 按照枚举值的 key 和 value 创建对应的 napi value
#define GEN_ENUM_KV(env, enum, key, jsKey, jsVal) do {                 \napi_create_string_utf8((env), #key, NAPI_AUTO_LENGTH, &(jsKey));  \napi_create_int32((env), enum::key, &(jsVal));                     \
} while (0)// 用以减少定义 napi_property_descriptor 模板代码
#define SET_ENUM_KV(jsKey, jsVal)                                                  \{ nullptr, (jsKey), nullptr, nullptr, nullptr, (jsVal), napi_default, nullptr }

创建并初始化所需的 napi_value

napi_value enumKeys[3] = {nullptr};  // 3: num of EnumClass
napi_value enumVals[3] = {nullptr};  // 3: num of EnumClassGEN_ENUM_KV(env, EnumClass, VAL_A, enumKeys[0], enumVals[0]);
GEN_ENUM_KV(env, EnumClass, VAL_B, enumKeys[1], enumVals[1]);
GEN_ENUM_KV(env, EnumClass, VAL_C, enumKeys[2], enumVals[2]);  // 2: index array

枚举类的实现应用到js Object

// 创建一个 napi_property_descriptor 数组,用以容纳js枚举值napi_property_descriptor desc[] = {NAPI_SET_VALUE(enumKeys[0], enumVals[0]),NAPI_SET_VALUE(enumKeys[1], enumVals[1]),NAPI_SET_VALUE(enumKeys[2], enumVals[2]),  // 2: index array
};napi_define_properties(env, enumObject, sizeof(desc) / sizeof(desc[0]), desc);napi_set_property(env, enumObject, enumVals[0], enumKeys[0]),
napi_set_property(env, enumObject, enumVals[1], enumKeys[1]),
napi_set_property(env, enumObject, enumVals[2], enumKeys[2]),  // 2: index array

完整示例代码

Native侧 C++ 代码。

enum EnumClass { VAL_A = 0,VAL_B,VAL_C,
};#define GEN_ENUM_KV(env, enum, key, jsKey, jsVal) do {                 \napi_create_string_utf8((env), #key, NAPI_AUTO_LENGTH, &(jsKey));  \napi_create_int32((env), enum::key, &(jsVal));                     \
} while (0)#define NAPI_SET_VALUE(jsKey, jsVal)                                                  \{nullptr, (jsKey), nullptr, nullptr, nullptr, (jsVal), napi_default, nullptr}static SomeFunction(napi_env env /* args... */)
{// ... ...napi_value enumObject = nullptr;napi_create_object(env, &enumObject);napi_value enumKeys[3] = {nullptr};  // 3: num of EnumClassnapi_value enumVals[3] = {nullptr};  // 3: num of EnumClassGEN_ENUM_KV(env, EnumClass, VAL_A, enumKeys[0], enumVals[0]);GEN_ENUM_KV(env, EnumClass, VAL_B, enumKeys[1], enumVals[1]);GEN_ENUM_KV(env, EnumClass, VAL_C, enumKeys[2], enumVals[2]);  // 2: index arraynapi_property_descriptor desc[] = {NAPI_SET_VALUE(enumKeys[0], enumVals[0]),NAPI_SET_VALUE(enumKeys[1], enumVals[1]),NAPI_SET_VALUE(enumKeys[2], enumVals[2]),  // 2: index array};napi_set_property(env, enumObject, enumVals[0], enumKeys[0]),napi_set_property(env, enumObject, enumVals[1], enumKeys[1]),napi_set_property(env, enumObject, enumVals[2], enumKeys[2]),  // 2: index arraynapi_define_properties(env, enumObject, sizeof(desc) / sizeof(desc[0]), desc);// ... ...
}

对应的枚举类的 .d.ts 描述文件。

export enum EnumClass {VAL_A = 0,VAL_B,VAL_C,
}

与上述逻辑相匹配的js代码。

const EnumClass = {0: "VAL_A",1: "VAL_B",2: "VAL_C",VAL_A: 0,VAL_B: 1,VAL_C: 2,
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/738870.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Matlab马尔可夫链蒙特卡罗法(MCMC)估计随机波动率(SV,Stochastic Volatility) 模型|附代码数据

全文下载链接:http://tecdat.cn/?p=16708 最近我们被客户要求撰写关于随机波动率的研究报告,包括一些图形和统计输出。 波动率是一个重要的概念,在金融和交易中有许多应用。它是期权定价的基础。波动率还可以让您确定资产配置并计算投资组合的风险价值 (VaR) 甚至波动率本身…

2024.7.5 鲜花

菜就多练空白とカタルシス——TOGENASHI TOGEARI。震惊,K某He 强推竟然是这首歌,三天重复上百遍…… どれだけ手に入れても どれだけ自分のものにしてもしてもしても 追いつけないな 高望みしすぎなんて 腐ったような言葉 誰しも誰よりも優れて欲しくはないんだよ 理由はただ…

泛娱乐出海新风口,视频云技术需要怎样的融合创新?

泛娱乐的音视频技术随着出海在演进,交互和内容的技术是内核,也在融合。 泛娱乐的音视频技术随着出海在演进,交互和内容的技术是内核,也在融合。 面向出海,虽然娱乐社交这个行业由来已久,但近几年的商业模式发生了巨大变化,比如行业刚兴起时,大家要先把DAU做大之后再…

米尔瑞米派集聚5种操作系统,兼顾学习开发和项目产品需要的派

米尔电子发布的瑞萨第一款MPU生态板卡-瑞米派(Remi Pi),采用瑞萨RZ/G2L双核A55芯片,接口丰富,全面兼容树莓派的扩展模块。瑞米派支持五种系统,兼顾学习开发和项目产品需要。软件提供五种软件系统分别为:基于Yocto构建的两种系统,一种是支持通用功能的精简型系统,另一种…

echarts中Label标签与数据项颜色设置为同一种颜色

echarts5中默认标签颜色不会跟数据项颜色保持一致,而是全都是黑色。想要实现label颜色和它的数据项颜色一致,需要手动继承颜色,设置label{ color: inherit}即可解决label标签颜色与数据项颜色一致。 https://echarts.apache.org/examples/zh/editor.html?c=pie-simple 注意…

GaussDB AI新特性:gs_index_advise推荐索引

GaussDB的AI新特性,可以把SQL文本嵌套在函数中,数据库会返回一个创建合适索引的列gs_index_advise(text) 描述:针对单条查询语句推荐索引。 参数: SQL语句字符串 返回值类型: record 一、通常的SQL优化会通过参数调优的方式进行调整,例如如下参数set enable_fast_query_s…

Packing Python to exe(打包Python成EXE文件)

Python文件要执行需要Python环境,如果package成EXE文件则可以随意放在任意主机上去执行。package步骤如下: 1. 安装pythoninstaller (pip install pyinstaller) 2.安装auto-py-to-exe(有UI界面,很方便使用)(pip install auto-py-to-exe) 3.然后直接运行命令auto-py-to-e…

Sqlalchemy 连接SQL Server 登录失败

实验系统环境 Windows平台 Sqlalchemy 2.0.23 Python 3.10 SQL Server 2012 aioodbc 0.5.0 问题详情 sqlalchemy.exc.InterfaceError: (pyodbc.InterfaceError) (28000, [28000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]登录失败。该登录名来自不受信任的域,不…

电脑使用什么远程控制软件?推荐使用安全软件ToDesk

当你面临紧急工作需求,但却和办公电脑相隔千里时,远程控制电脑就派上了用场! 初次使用远程控制软件的人,可能会担心使用时会不会存在信息被盗取,使用过后会不会发生被陌生人悄悄远控的情况 小社长向大家安利一个超好用的远程控制软件ToDesk!电脑远程控制高清不卡顿,传输…

便宜SSL证书申请Lets Encrypt泛域名SSL证书

随着互联网的飞速发展,网络安全问题愈发凸显其重要性。而HTTPS协议作为保障网站数据传输安全的重要手段,已经得到了广泛的应用。 申请Lets Encrypt便宜泛域名SSL证书步骤1. 登录来此加密网站,输入域名,可以勾选泛域名和包含根域。2. 选择加密方式,一般选择默认就可以了,也…

ToDesk云电脑实测!轻松应对游戏电竞、AIGC创作、设计建模等场景

万物智联时代,现代社会对数字计算的需求呈指数级增长。当算力成为推动技术创新和应用发展的重要引擎,云电脑产业正在悄然占据国内算力应用的市场,成为新时代的数字经济发展方向。1云电脑,顾名思义,是一台随时运行在云上的“电脑”,操作系统、存储、运算都能在云端上进行,…

ToDesk智能无损画质是什么功能?如何使用1

能跨设备跨系统远程控制设备的ToDesk相信大家都有用过,它不仅有流畅的远控体验,而且开发了许多实用的插件功能。 比如能直接从硬盘高速传资料的文件传输功能,官方实测能达到12m/s,还有能远程开关机,太方便远程办公完需要关电脑的打工人了。最近小社长还发现ToDesk远程控制…