当前位置: 首页 > news >正文

[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
}

逻辑比较简单,步骤如下

  1. 先通过window对象拿到widthheight;
  2. 通过方法as_f64将JsValue转换成f64类型;
  3. 通过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)。

在我们的问题场景中,我们用asf64转换成了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);
}

按照之前的f64u32的经验,打印的结果应该是:-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中的boolStringf64f64与其它Rust数字之间的转换需要依赖as关键字。但是,如果数字类型实现了TryFrom<T>这个trait,就不要使用as关键字来进行转换。

今天就到这里,欢迎大家留言交流。

相关文章:

[2023.09.26]: JsValue的转换体验与as关键字的浅析

昨天解决了焦点问题&#xff0c;今天就开始搬砖了。本以为可以一帆风顺&#xff0c;但是还是遇到了几个问题&#xff0c;不过还好&#xff0c;都被一一解决&#xff0c;这里我分享一下JsValue的转换体验以及关键字as的使用浅析。 场景描述 我是在什么情况下遇到JsValue的转换…...

SpringBoot Validation入参校验国际化

在 Spring Boot 中&#xff0c;可以使用 Validation 和国际化来实现对入参的校验。 常用的校验 NotNull验证字段值不能为 nullNotEmpty验证字段值不能为 null 或空字符串NotBlank验证字符串字段值不能为空、null&#xff0c;并且必须至少包含一个非空白字符Size验证字符串、…...

树莓集团涉足直播产业园区运营,成都直播产业园区再添黑马

树莓集团涉足成都直播产业园运营领域&#xff0c;这一消息引起了业界的广泛关注。在这个无限可能的直播领域中&#xff0c;树莓集团将与上市公司德商产投紧密合作&#xff0c;立志为成都直播行业的发展注入新的活力。成都天府蜂巢直播产业园推行着一系列创新的政策措施&#xf…...

中小学教师ChatGPT的23种用法

原文&#xff1a;中小学教师ChatGPT的23种用法 近日&#xff0c;ChatGPT引发舆论风暴&#xff0c;火遍全球。作为一款生成式人工智能软件&#xff0c;ChatGPT可以就任何议题生成文本&#xff0c;完成包括回答问题&#xff0c;撰写文章、论文、诗歌在内的多种工作。各界盛赞其“…...

Ubuntu性能分析-ftrace 底层驱动

1、框架介绍 ftrace内核驱动可以分为几部分:ftrace framework,RingBuffer,debugfs,Tracepoint,各种Tracer。 ftrace框架是整个ftrace功能的纽带,包括对内和的修改,Tracer的注册,RingBuffer的控制等等。 RingBuffer是静态动态ftrace的载体。 debugfs则提供了用户空间…...

网盘搜索引擎:点亮知识星空,畅享数字宝藏!

大家好&#xff01;作为一名资深的网络产品运营人员&#xff0c;我今天要向大家介绍一款让你受益匪浅的神奇工具——网盘搜索引擎&#xff01;它可以帮助你免费搜索查询各种云盘共享资源&#xff0c;包括影视作品、纪录片、小说、动漫等等。现在&#xff0c;我们急需网络流量&a…...

Mysql以key-val存储、正常存储的区别

场景 你作为一个服务端工程师&#xff0c;假设产品要求设计这么一个页面&#xff0c;页面上包含很多模块&#xff0c;每个模块都可以单独进行变更&#xff0c;有些模块是富文本。 实现方式有很多&#xff0c;我们来聊比较常用的两种&#xff0c;看看mysql的表如何设计。 第一…...

MySQL 索引优化实践(单表)

目录 一、前言二、表数据准备三、常见业务无索引查询耗时测试3.1、通过订单ID / 订单编号 查询指定订单3.2、查询订单列表 四、订单常见业务索引优化实践4.1、通过唯一索引和普通索引优化通过订单编号查询订单信息4.2、通过普通联合索引优化订单列表查询4.2.1、分析查询字段的查…...

react create-react-app v5配置 px2rem (暴露 eject方式)

环境信息&#xff1a; create-react-app v5 “react”: “^18.2.0” “postcss-plugin-px2rem”: “^0.8.1” 配置步骤&#xff1a; 我这个方式是 npm run eject 暴露 webpack配置的方法 1.安装 postcss-plugin-px2rem 和 lib-flexible cnpm install postcss-plugin-px2rem…...

AVL树的实现及原理

目录 AVL树的由来 AVL的实现原理 左单旋 右单旋 先左后右 先右后左 总结 AVL树的由来 查找&#xff0c;无论在什么情况下都与我们息息相关。在我们学习数组阶段学习到了线性查找&#xff0c;可是它的效率很低下&#xff0c;又演变出来了二分查找&#xff0c;它的效率非常…...

NestJs和Vite使用monorepo管理项目中,需要使用共享的文件夹步骤

NestJs和Vite使用monorepo管理项目中,需要使用共享的文件夹步骤 1 首先需要将nest-cli打包的功能通过webpack接管 nest-cli.json文件内容 {"$schema": "https://json.schemastore.org/nest-cli","collection": "nestjs/schematics",…...

我用PYQT5做的第一个实用的上位机项目(三)

基本的程序框架&#xff1a; 因为自己不是专业的程序员&#xff0c;只是一个搞电气控制的“票友”&#xff0c;所以尽量减少手动输入 代码量&#xff0c;能在Qt Dsigner里面完成的组态就不要放在代码里面完成。 在框架的建设方面&#xff0c;尽量做到集中和整合&#xff0c;位…...

代谢组学分析平台(二)

GC/MS分析生物样本为何要衍生化处理&#xff1f;有哪些衍生化的方法&#xff1f; GC的流动相为气体&#xff08;通常为高纯氦&#xff09;&#xff0c;这就要求被分析物必须能够气化&#xff0c;而生物样本中很多内源性代谢物都含有极性基团&#xff0c;具有沸点高、不易气化特…...

【统计学】Top-down自上而下的角度模型召回率recall,精确率precision,特异性specificity,模型评价

最近在学 logistic regression model&#xff0c;又遇见了几个之前的老面孔。 召回率recall, 精确率precision&#xff0c;特异性spcificity&#xff0c;准确率accuracy&#xff0c;True positive rate&#xff0c;false positive rate等等名词在学习之初遇到的困难在于&#x…...

AutoDL使用tensorboard

目录 一&#xff0c;训练形成log文件 二. 切换logs目录 三&#xff0c;在AutoPanel中访问TensorBoard 一&#xff0c;训练形成log文件 例子&#xff1a; from torch.utils.tensorboard import SummaryWriter import numpy as npwriter SummaryWriter() for x in range(1, …...

代谢组学分析手段(一)

核磁共振技术&#xff08;Nuclear Magnetic Resonance, NMR&#xff09; 定义&#xff1a;指核磁矩不为零的原子核在外磁场的作用下&#xff0c;核自旋能级发生塞曼分裂&#xff0c;共振吸收某一特定频率的射频辐射的物理过程。 优点&#xff1a; &#xff08;1&#xff09;…...

网络基础入门(网络基础概念详解)

本篇文章主要是对网络初学的概念进行解释&#xff0c;可以让你对网络有一个大概整体的认知。 文章目录 一、简单认识网络 1、1 什么是网络 1、2 网络分类 二、网络模型 2、1OSI七层模型 2、1、1 简单认识协议 2、1、2 OSI七层模型解释 2、2 TCP/IP五层(或四层)模型 三、网络传…...

简化任务调度与管理:详解XXL-Job及Docker Compose安装

在现代应用程序开发中&#xff0c;任务调度和管理是至关重要的一部分。XXL-Job是一个强大的分布式任务调度平台&#xff0c;它使得任务的调度和管理变得更加轻松和高效。本文将介绍XXL-Job的基本概念&#xff0c;并详细演示如何使用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…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...

Leetcode33( 搜索旋转排序数组)

题目表述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

echarts使用graphic强行给图增加一个边框(边框根据自己的图形大小设置)- 适用于无法使用dom的样式

pdf-lib https://blog.csdn.net/Shi_haoliu/article/details/148157624?spm1001.2014.3001.5501 为了完成在pdf中导出echarts图&#xff0c;如果边框加在dom上面&#xff0c;pdf-lib导出svg的时候并不会导出边框&#xff0c;所以只能在echarts图上面加边框 grid的边框是在图里…...