[2023.09.26]: JsValue的转换体验与as关键字的浅析
昨天解决了焦点问题,今天就开始搬砖了。本以为可以一帆风顺,但是还是遇到了几个问题,不过还好,都被一一解决,这里我分享一下JsValue的转换体验以及关键字as的使用浅析。
场景描述
我是在什么情况下遇到JsValue的转换的呢?获取当前窗口的内部宽度和内部高度。api的接口定义如下:
pub fn inner_width(&self) -> Result<JsValue, JsValue>
pub fn inner_height(&self) -> Result<JsValue, JsValue>
我使用当前窗口的内部宽度和内部高度的地方在Modal组件中:
#[derive(Properties, Clone, PartialEq)]
pub struct Props {...#[prop_or(200)]pub width: u32,#[prop_or(500)]pub height: u32,
}
也就是说,我要将JsValue转换成u32类型。
问题解决
先看这个问题最终是怎么解决的吧。和Javascript代码比起来,是稍微复杂了一点点。
pub fn get_window_size() -> Option<(u32, u32)> {if let Some(window) = get_window() {let width = window.inner_width().unwrap_or_else(|_| JsValue::from_f64(default_width1));let height = window.inner_height().unwrap_or_else(|_| JsValue::from_f64(default_height1));let width1: f64 = width.as_f64()?;let height1: f64 = height.as_f64()?;let width2 = width1 as u32;let height2 = height1 as u32;return Some((width2, height2));}None
}
逻辑比较简单,步骤如下
- 先通过window对象拿到
width和height; - 通过方法
as_f64将JsValue转换成f64类型; - 通过rust的
as关键字将f64类型转换成u32类型;
问题展开
从问题的解决层面上来说,明确上面3步,就可以拿到我们需要的数据,但是这显然只是冰山一角。水下面的东西很多,这里我挑2个容易的来说。
关于JsValue的数据转换
JsValue定义在wasm_bindgen中,关于数据转换的接口有下面这几个:
pub fn as_bool(&self) -> Option<bool>;
pub fn as_f64(&self) -> Option<f64>;
pub fn as_string(&self) -> Option<String>;pub const fn from_bool(b: bool) -> JsValue;
pub fn from_f64(n: f64) -> JsValue;
pub fn from_str(s: &str) -> JsValue;
也就是说,wasm_bindgen::JsValue中,只关心布尔值,字符串和数字,而数字在rust中使用的是f64,即rust std中支持的容量最大,精度最高的数字。JsValue代表了Javascript环境中的数据。因此,了解这一点,我们就可以自由的进行Javascript和Rust的数据交换了。
关于as
在上面的代码中,我们通过rust的as关键字,将f64数字类型转换成了u32数字类型。
在Rust中,as关键字可以用于类型转换,将一个类型转换为另一个类型,这里的类型必须原始类型(primitive types),但显然不是指所有的原始类型。
什么是原始类型呢?原始类型是Rust语言的基本的数据类型,它们是语言的一部分。Rust语言的原始类型包括一下几种:
布尔类型(bool):表示逻辑值,只能是true或false。
字符类型(char):表示单个Unicode字符。
整数类型(integer):包括有符号整数(i8、i16、i32、i64、isize)和无符号整数(u8、u16、u32、u64、usize)。
浮点数类型(floating-point):包括单精度浮点数(f32)和双精度浮点数(f64)。
元组类型(tuple):可以包含多个不同类型的值。
数组类型(array):包含固定长度的相同类型的值。
切片类型(slice):对数组的引用,可以动态指定长度。
指针类型(pointer):包括原始指针(const T和mut T)和引用(&T)。
在我们的问题场景中,我们用as将f64转换成了u32。难道还能将tuple转换成u32不成,显然是不可能的。还好编译器会给出提示。
let num1 = (-33, -5);let num: u32 = num1 as u32;
报错:
3 | let num: u32 = num1 as u32;| ^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
其实在这里,我用as关键字是迫不得已的。因为我没有在u32这个类型上找到impl TryFrom<f64> for u32这样的方法。那将f64类型的数据转换成u32类型的数据,编译器没有报错,是不是就意味着没有问题呢?在我们的问题场景中,应该是没有问题的。但是从数据本身的角度,是有问题的。
fn main() {let num: f64 = -323.3;let num1: u32 = num as u32;println!("numbers:{}, {}", num, num1);
}
打印结果如下:
numbers:-323.3, 0
我想你应该总结处理这里的规律了吧,再看看下面这段就让你大跌眼镜了:
fn main() {let num: i32 = -3;let num1: u32 = num as u32;println!("numbers:{}, {}", num, num1);
}
按照之前的f64到u32的经验,打印的结果应该是:-3, 0,对吧?
错,结果也让我吓一跳:
numbers:-3, 4294967293
而u32的最大数值是:4294967295。
这里的水有多深,我就不往下说了,我怕淹死在这里,哈哈。
正确的做法是:
fn main() {let num: i32 = -3;let num1: u32 = u32::try_from(num).unwrap_or_else(|_| 0);println!("numbers:{}, {}", num, num1);
}
所以,关于使用as来转换数据,如果类型本身实现了TryFrom<T> for ...,那么就不要使用as来进行类型转换。
总结
在基于wasm_bindgen的WebAssembly开发过程中,JsValue与Rust原始数据类型之间的转换会是家常便饭。对于JsValue来说,它只关心布尔值,字符串和数字,分别对应Rust中的bool,String和f64。f64与其它Rust数字之间的转换需要依赖as关键字。但是,如果数字类型实现了TryFrom<T>这个trait,就不要使用as关键字来进行转换。
今天就到这里,欢迎大家留言交流。
相关文章:
[2023.09.26]: JsValue的转换体验与as关键字的浅析
昨天解决了焦点问题,今天就开始搬砖了。本以为可以一帆风顺,但是还是遇到了几个问题,不过还好,都被一一解决,这里我分享一下JsValue的转换体验以及关键字as的使用浅析。 场景描述 我是在什么情况下遇到JsValue的转换…...
SpringBoot Validation入参校验国际化
在 Spring Boot 中,可以使用 Validation 和国际化来实现对入参的校验。 常用的校验 NotNull验证字段值不能为 nullNotEmpty验证字段值不能为 null 或空字符串NotBlank验证字符串字段值不能为空、null,并且必须至少包含一个非空白字符Size验证字符串、…...
树莓集团涉足直播产业园区运营,成都直播产业园区再添黑马
树莓集团涉足成都直播产业园运营领域,这一消息引起了业界的广泛关注。在这个无限可能的直播领域中,树莓集团将与上市公司德商产投紧密合作,立志为成都直播行业的发展注入新的活力。成都天府蜂巢直播产业园推行着一系列创新的政策措施…...
中小学教师ChatGPT的23种用法
原文:中小学教师ChatGPT的23种用法 近日,ChatGPT引发舆论风暴,火遍全球。作为一款生成式人工智能软件,ChatGPT可以就任何议题生成文本,完成包括回答问题,撰写文章、论文、诗歌在内的多种工作。各界盛赞其“…...
Ubuntu性能分析-ftrace 底层驱动
1、框架介绍 ftrace内核驱动可以分为几部分:ftrace framework,RingBuffer,debugfs,Tracepoint,各种Tracer。 ftrace框架是整个ftrace功能的纽带,包括对内和的修改,Tracer的注册,RingBuffer的控制等等。 RingBuffer是静态动态ftrace的载体。 debugfs则提供了用户空间…...
网盘搜索引擎:点亮知识星空,畅享数字宝藏!
大家好!作为一名资深的网络产品运营人员,我今天要向大家介绍一款让你受益匪浅的神奇工具——网盘搜索引擎!它可以帮助你免费搜索查询各种云盘共享资源,包括影视作品、纪录片、小说、动漫等等。现在,我们急需网络流量&a…...
Mysql以key-val存储、正常存储的区别
场景 你作为一个服务端工程师,假设产品要求设计这么一个页面,页面上包含很多模块,每个模块都可以单独进行变更,有些模块是富文本。 实现方式有很多,我们来聊比较常用的两种,看看mysql的表如何设计。 第一…...
MySQL 索引优化实践(单表)
目录 一、前言二、表数据准备三、常见业务无索引查询耗时测试3.1、通过订单ID / 订单编号 查询指定订单3.2、查询订单列表 四、订单常见业务索引优化实践4.1、通过唯一索引和普通索引优化通过订单编号查询订单信息4.2、通过普通联合索引优化订单列表查询4.2.1、分析查询字段的查…...
react create-react-app v5配置 px2rem (暴露 eject方式)
环境信息: create-react-app v5 “react”: “^18.2.0” “postcss-plugin-px2rem”: “^0.8.1” 配置步骤: 我这个方式是 npm run eject 暴露 webpack配置的方法 1.安装 postcss-plugin-px2rem 和 lib-flexible cnpm install postcss-plugin-px2rem…...
AVL树的实现及原理
目录 AVL树的由来 AVL的实现原理 左单旋 右单旋 先左后右 先右后左 总结 AVL树的由来 查找,无论在什么情况下都与我们息息相关。在我们学习数组阶段学习到了线性查找,可是它的效率很低下,又演变出来了二分查找,它的效率非常…...
NestJs和Vite使用monorepo管理项目中,需要使用共享的文件夹步骤
NestJs和Vite使用monorepo管理项目中,需要使用共享的文件夹步骤 1 首先需要将nest-cli打包的功能通过webpack接管 nest-cli.json文件内容 {"$schema": "https://json.schemastore.org/nest-cli","collection": "nestjs/schematics",…...
我用PYQT5做的第一个实用的上位机项目(三)
基本的程序框架: 因为自己不是专业的程序员,只是一个搞电气控制的“票友”,所以尽量减少手动输入 代码量,能在Qt Dsigner里面完成的组态就不要放在代码里面完成。 在框架的建设方面,尽量做到集中和整合,位…...
代谢组学分析平台(二)
GC/MS分析生物样本为何要衍生化处理?有哪些衍生化的方法? GC的流动相为气体(通常为高纯氦),这就要求被分析物必须能够气化,而生物样本中很多内源性代谢物都含有极性基团,具有沸点高、不易气化特…...
【统计学】Top-down自上而下的角度模型召回率recall,精确率precision,特异性specificity,模型评价
最近在学 logistic regression model,又遇见了几个之前的老面孔。 召回率recall, 精确率precision,特异性spcificity,准确率accuracy,True positive rate,false positive rate等等名词在学习之初遇到的困难在于&#x…...
AutoDL使用tensorboard
目录 一,训练形成log文件 二. 切换logs目录 三,在AutoPanel中访问TensorBoard 一,训练形成log文件 例子: from torch.utils.tensorboard import SummaryWriter import numpy as npwriter SummaryWriter() for x in range(1, …...
代谢组学分析手段(一)
核磁共振技术(Nuclear Magnetic Resonance, NMR) 定义:指核磁矩不为零的原子核在外磁场的作用下,核自旋能级发生塞曼分裂,共振吸收某一特定频率的射频辐射的物理过程。 优点: (1)…...
网络基础入门(网络基础概念详解)
本篇文章主要是对网络初学的概念进行解释,可以让你对网络有一个大概整体的认知。 文章目录 一、简单认识网络 1、1 什么是网络 1、2 网络分类 二、网络模型 2、1OSI七层模型 2、1、1 简单认识协议 2、1、2 OSI七层模型解释 2、2 TCP/IP五层(或四层)模型 三、网络传…...
简化任务调度与管理:详解XXL-Job及Docker Compose安装
在现代应用程序开发中,任务调度和管理是至关重要的一部分。XXL-Job是一个强大的分布式任务调度平台,它使得任务的调度和管理变得更加轻松和高效。本文将介绍XXL-Job的基本概念,并详细演示如何使用Docker Compose进行快速安装和配置。 什么是X…...
QByteArray字节数组
QByteArray字节数组 文章目录 QByteArray字节数组1.1 QByteArray类基本使用说明1.2 设置数组字节大小1.3 返回数组大小1.4 将数据转为其他类型1.5 将数据转为C语言的字符指针返回1.6 数组数据追加1.7 清除数组数据为指定值1.8 数组数据插入1.9 删除指定位置指定长度的数据1.10 …...
ubuntu20.04.3中qt程序界面嵌套另一个qt界面
先上代码 #include "mainwindow.h" #include <QApplication> #include <iostream> using namespace std; #ifdef _WIN32// Windows 平台的代码 #include <windows.h> #elif __linux__// Linux 平台的代码// ...#include <X11/Xlib.h> #else…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
ubuntu22.04有线网络无法连接,图标也没了
今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...
算法—栈系列
一:删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {stack<char> st;for(int i 0; i < s.size(); i){char target s[i];if(!st.empty() && target st.top())st.pop();elsest.push(s[i]);}string ret…...
使用python进行图像处理—图像滤波(5)
图像滤波是图像处理中最基本和最重要的操作之一。它的目的是在空间域上修改图像的像素值,以达到平滑(去噪)、锐化、边缘检测等效果。滤波通常通过卷积操作实现。 5.1卷积(Convolution)原理 卷积是滤波的核心。它是一种数学运算,…...
Linux 内存管理调试分析:ftrace、perf、crash 的系统化使用
Linux 内存管理调试分析:ftrace、perf、crash 的系统化使用 Linux 内核内存管理是构成整个内核性能和系统稳定性的基础,但这一子系统结构复杂,常常有设置失败、性能展示不良、OOM 杀进程等问题。要分析这些问题,需要一套工具化、…...
