【社区投稿】自动特征auto trait的扩散规则
自动特征auto trait
的扩散规则
公式化地概括,auto trait = marker trait + derived trait
。其中,等号右侧的marker
与derived
是在Rustonomicon书中的引入的概念,鲜见于Rust References。所以,若略感生僻,不奇怪。
marker trait
与derived trait
精准概括了auto trait
功能的两面性
前者指明
auto trait
实现类具备了由rustc
编译器和std
标准库对其约定的“天赋异能 intrinsic properties”。后者描述了这些“天赋异能”沿
auto trait
实现类数据结构【自内及外】的继承性与扩散性。
接下来逐一解释。
marker trait
标识“天赋”特征是什么
既然是“天赋”,那么auto trait
就没有任何抽象成员方法待被“后天实现”或关联项待被“后天赋值” — 这也是marker trait
别名的由来。rustc
甚至未配备专项检查器以静态分析与推断 @Rustacean 对auto trait
的实现是否合理。类似于unsafe
块,@Rustacean 需向rustc
承诺:知道自已正在干什么,和提交可供其它程序模块信任的“天赋异能“代码实现。否则,运行时程序就会执行出未定义行为 U.B.。相比于传统的std
程序接口和rustc
内存安全承诺,这是一项“反向契约” — 即,由rustc
充当“甲方”和规划功能要求,而由 @Rustacean 充当“乙方”完成功能代码和提供正确性保证。在硕大的Rust
标准库中,这类“天赋异能“的”反向契约”并不多见,但包括
derived trait
明确“天赋”特征如何扩散
概括起来,auto trait
的扩散规则就四个字“由内及外”。其遇到不同的场景,伴有不同解释的扩散链条
场景一:变量 ➜ 指针
以变量的数据类型为内,和以指向该变量值的指针/引用为外 — 变量值(数据类型T
)实现的auto trait
会自动扩散至它的各类指针与引用:
&T
&mut T
*const T
*mut T
所以,该扩散链条也被记作【类型 ➜ 指针】。
场景二:字段 ➜ 结构体
以字段的数据类型为内,和以父数据结构为外 — 所有字段(数据类型)都实现的auto trait
会自动扩散至它们的紧上一层数据结构:
structs
enums
unions
tuples
所以,该扩散链条也被记作【字段 ➜ 结构】。
场景三:元素 ➜ 集合
以集合元素的数据类型为内,和以集合容器为外 — 由元素(数据类型T
)实现的auto trait
会自动扩散至该元素的紧上一层集合容器:
[T; n]
[T]
Vec<T>
场景四:捕获变量 ➜ 闭包
以捕获变量的数据类型为内,和以闭包为外 — 所有捕获变量(数据类型)都实现的auto trait
会自动扩散至引用(或所有权占用)这些捕获变量的闭包。
场景五:函数 ➜ 函数指针
函数项fn
与函数指针fn ptr
总是会被rustc
编译时自动实现全部auto trait
。
扩散链条的“串连”
前四个场景的扩散链是可以多重嵌套衔接的。举个例子,Vec<Wrapping<u8>>
一定满足trait Send
限定条件,因为这条扩散链条的存在:

再举个更复杂的例子,假设有如下枚举类
enum Test<'a> {Str(&'a String),Num(u8)
}
那么Vec<Test>
也一定满足trait Send
限定条件,因为此扩散链条的存在:

auto trait
扩散链条的“阻断”
安装
nightly
版rustc
编译器。然后,在代码中,开启
#![feature(negative_impls)]
的feature-gate
编译开关,否定实现
auto trait
。比如,impl !Unpin for Test {}
于是,rustc
就不会再对遇到的【类型定义】自动添加曾被否定实现过的auto trait
了。在众多auto trait
中,仅trait Unpin
可绕过对nightly
编译工具链的依赖和仅凭stable
标准库内符号类型std::marker::PhantomPinned
定义的幻影字段阻止rustc
悄悄地实现自动特征。
【幻影字段】是仅作用于编译时的零成本抽象项。它被用来帮助编译器理解 @Rustacean 提交的代码和推断 @Rustacean 的程序设计意图。其语义功能很像
typescript
中的【@ 装饰器】。即,
辅助代码静态分析
辅助编译器生成垫片程序
编译后立即抹除
对【运行时】不可见 — 这也是【零成本】的由来。但,世间任何事物都有两面性和是双刃剑。“零成本”是省
CPU
,但更费脑细胞呀!Rust
编程的心智成本高已是行业共识了。另值一提的是,【
Rust
幻影字段】与【typescript
装饰器】皆都不同于【Java
的 @ 注释】,因为
前者是给编译器看和解读的 — 充其量是代码正文的旁白注脚。
后者是给运行时
VM
用和执行的 — 这已算是正文指令的一部分了。它们就是两个不同“位面”的东西。
我日常仅用过
std::marker::PhantomPinned
与std::marker::PhantomData
两类幻影字段
前者解决
stable
编译工具链对trait Unpin
的否定实现 — 就是这里正在讲的事后者被用于“类型状态
Type State Pattern
”设计模式中,将【运行时】对象状态的(动态)信息编码入【编译时】对象类型的(静态)定义里,以扩展Rust
类型系统的应用场景至对状态集的“状态管理”。若您对“类型状态”设计模式有兴趣,推荐移步至我的另一篇主题文章对照 OOP 浅谈【类型状态】设计模式保证有收获。这闲篇扯远了,让咱们重新回到文章的主题上来。
请细读下面自引用结构体的类型定义(特别含注释内容)和体会std::marker::PhantomPinned
如何被用来声明结构体内的幻影字段:
use ::std::marker::PhantomPinned;
struct SelfReferential {// 整个结构体内唯一包含了有效信息的字段。a: String,// 自引用前一个字段`a`的值。ref_a: *const String,// 1. 这是对【幻影字段】的定义// 2. 因为该字段并不会真的被后续功能代码用到,// 所以为了压制来自编译器的`useless field`警告,// 字段名以`_`为前缀_marker: PhantomPinned
} // 于是,自引用结构体`Test`就是 !Unpin 的了
即便不太理解,也请不要质疑【自引用结构体】的存在必要性。至少在异步程序块中,跨.await
轮询点的变量引用都依赖这套机制。仅因为async {}
语法糖把每次构造trait Future
实现类的细节都隐藏了起来,所以 @Rustacean 对自引用结构体的直观感受会比较弱。
auto trait
扩散不至的自定义数据结构
若数据结构定义内含有未实现auto trait
的字段(比如,
use ::std::env::Vars;
struct Dumb(Vars);
其中Dumb.0
字段Vars
明确是!Send
的),那么 @Rustacean 就有必要考虑
要么,重新规划程序设计,以规避要求
struct Dumb
满足trait Send
限定条件要么,给
struct Dumb
添加unsafe
的auto trait
实现块。unsafe impl Send for Dumb {};
后者的unsafe impl
语法前缀就是rustc
对程序作者最后的警告:“你真的明白,你正在做什么事吗?”。
【快排序】 综合例程
先贴源码,再做详解。敲黑板强调:代码内的注释同样重要呀!推荐同正文一样重视和仔细阅读。
fn quick_sort<T: Ord + Send>(v: &mut [T]) {if v.len() <= 1 {return;}let mid = {let pivot = v.len() - 1;let mut i = 0;for j in 0..pivot {if v[j] <= v[pivot] {v.swap(i, j);i += 1;}}v.swap(i, pivot);i};// 1. 此处,虽然 lo 与 hi 是两个崭新的【切片】胖指针实例,// 但由【切片】胖指针引用的底层 Vec<i32> 数据值却只有// 一份呀!let (lo, hi) = v.split_at_mut(mid);// 2. 所以,后续的【多线程+递归】是修改的同一个 Vec<i32> // 实例。rayon::join(|| quick_sort(lo),|| quick_sort(hi));// 3. 至此,虽然此函数没有返回值,但仍可沿函数的【输入输出】// 实参 v: &mut [T] 向调用端传递排序结果。
}
fn main() {use ::rand::prelude::*;// 1. 生成一个大数字集合let mut numbers: Vec<i32> = (1000..10000).collect();// 2. 乱序数组内容numbers.shuffle(&mut rand::thread_rng()); // 3. 多线程快排序quick_sort(&mut numbers); // 4. 打印排序结果println!("Sorted: {:?}", &numbers[..10]);// 5. 一个单例 Vec<i32> 对象贯穿整个多线程快排序 demo 始终。
}
上述例程的难点并不是rayon::join()
如何在后台悄悄唤起多个线程加速大数据集【快排序】 — 这不需要 @Rustacean 操心,咱们只要多读读 API 文档和了解Work Stealing工作原理就足够了。相反,曾经困惑过我一段时间的痛点是:
为什么虽然泛型类型参数<T: Ord + Send>
的书面语义是“跨线程·数据复制”但程序的实际执行结果却是对Vec<i32>
单例的“跨线程·内存共享”?即,多个线程透过【切片】胖指针,修改同一个Vec<T>
变长数组实例。
推导明白这条逻辑链(元素Send
➜ 集合Sync
)先后耗费了我不少心神。但总结起来也无非如下几步:
依据前文介绍的
auto trait
扩散规则,对特征trait Send
和泛型类型参数T
,构造初始扩散链条:输入图片说明 依据
trait Send
至trait Sync
的(单向)转换关系,有<&S: Send> → <S: Sync>
。将 #2 代入 #1,进一步完善
trait Send
扩散链条,有输入图片说明 依据
rustc
赋予trait Sync
的语义,集合[T]
被允许跨线程引用与多线程共享又因为
fn quick_sort()
的形参是对Vec<i32>
实例的可修改引用&mut
,所以多个线程被允许并行修改同一个变长数组实例。
你不会以为故事就此结束了吧?难道你没有发觉例程中多线程代码有缺了点儿什么的异样吗?没错!细心的读者可能早就想问:
对单实例变长数组的并行修改,为什么未采用【读写锁RwLock
】或【互斥锁Mutex
】加以同步保护呢?甚至rustc
在编译时连警告提示都没有输出?What's wrong?
好问题!您有心了。快速回答是:虽然Vec<i32>
实例同时被多个线程并行修改不假,但每个线程并行修改的切片却只是同一变长数组内彼此衔接却并不相交的“子段”。所以,在快排序过程中,事实上没有任何数据竞争发生 — 这是彻头彻尾的算法胜利。果真,编程的尽头是数学与算法啊!此外,rustc
能顺利地接受与成功地编译这样的代码也足已破除人们以往对它保守且不变通的刻板印象。
结束语
这次就先分享这一个小知识点。文章里埋的有关Unpin
的坑以后再填。2024搞了一年的“鸿蒙Next ArkTs
”真不容易。哎!天大地大,饭辙最大。我是一颗螺丝钉,甲方爸爸需要什么,我就研究什么。但,年底写篇Rust
知识分享文章压压惊。
相关文章:
【社区投稿】自动特征auto trait的扩散规则
自动特征auto trait的扩散规则 公式化地概括,auto trait marker trait derived trait。其中,等号右侧的marker与derived是在Rustonomicon书中的引入的概念,鲜见于Rust References。所以,若略感生僻,不奇怪。 marker …...
【MySQL】第一弹----库的操作及数据类型
笔上得来终觉浅,绝知此事要躬行 🔥 个人主页:星云爱编程 🔥 所属专栏:MySQL 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 一、SQL 语句分类 DDL:数据定…...
【服务器主板】定制化:基于Intel至强平台的全新解决方案
随着数据处理需求不断增长,服务器硬件的发展也在持续推进。在这一背景下,为用户定制了一款全新的基于Intel至强平台的服务器主板,旨在提供强大的计算能力、优异的内存支持以及高速存储扩展能力。适用于需要高性能计算、大规模数据处理和高可用…...
Flutter路由工具类RouteUtils,可二次开发,拿来即用
一、RouteUtils路由核心类 /*** 路由封装*/ class RouteUtils {RouteUtils._();static final navigatorKey GlobalKey<NavigatorState>();// App 根节点Contextstatic BuildContext get context > navigatorKey.currentContext!;static NavigatorState get navigato…...
报错:No module named ‘pygeohash‘
如果你遇到这个错误: platform... using builtin-java classes where applicableTraceback (most recent call last):File "/home/spark-shell/AppLogDWD02.py", line 4, in <module>from pygeohash import encodeModuleNotFoundError: No module …...
SQL中的TRIM用法
TRIM 是 SQL 中用于去除字符串两端(左侧和右侧)的空格或特定字符的函数。这个函数常用于清理数据中的无效空白字符,尤其是在从外部系统导入数据时,常常会遇到数据两端有不必要的空格,使用 TRIM 可以去除这些多余的字符…...
AIGC在电影与影视制作中的应用:提高创作效率与创意的无限可能
云边有个稻草人-CSDN博客 目录 引言 一、AIGC在剧本创作中的应用 1.1 剧本创作的传统模式与挑战 1.2 AIGC如何协助剧本创作 1.3 未来的剧本创作:AI辅助的协同创作 二、AIGC在角色设计中的应用 2.1 传统角色设计的挑战 2.2 AIGC如何协助角色设计 三、AIGC在…...
【蓝桥杯——物联网设计与开发】拓展模块5 - 光敏/热释电模块
目录 一、光敏/热释电模块 (1)资源介绍 🔅原理图 🔅AS312 🌙简介 🌙特性 🔅LDR (2)STM32CubeMX 软件配置 (3)代码编写 (4&#x…...
深入探索openEuler Kernel:操作系统的心脏
title: 深入探索openEuler Kernel:操作系统的心脏 date: ‘2024-12-28’ category: blog tags: openEulerLinux Kernel操作系统性能优化 sig: Kernel archives: ‘2024-12’ author:way_back summary: openEuler Kernel作为openEuler操作系统的核心,扮演…...
Unity3d UGUI如何优雅的实现Web框架(Vue/Rect)类似数据绑定功能(含源码)
前言 Unity3d的UGUI系统与Web前端开发中常见的数据绑定和属性绑定机制有所不同。UGUI是一个相对简单和基础的UI系统,并不内置像Web前端(例如 Vue.js或React中)那样的双向数据绑定或自动更新UI的机制。UGUI是一种比较传统的 UI 系统ÿ…...
【JavaEE进阶】@RequestMapping注解
目录 📕前言 🌴项目准备 🌲建立连接 🚩RequestMapping注解 🚩RequestMapping 注解介绍 🎄RequestMapping是GET还是POST请求? 🚩通过Fiddler查看 🚩Postman查看 …...
Vue.js组件开发-自定义文件上传
在Vue.js中开发自定义文件上传组件,创建一个独立的Vue组件来处理文件选择和上传的逻辑。这个组件可以包含文件选择器、上传进度条、上传状态提示等元素,并根据需要进行自定义。 示例: <template><div class"file-upload"…...
CES Asia 2025的低空经济展区有哪些亮点?
CES Asia 2025(赛逸展)的低空经济展区有以下亮点: • 前沿科技产品展示: 多款新型无人机将亮相,如固定翼无人机和系留无人机的最新型号,其在监测、救援和货物运输等方面功能强大。此外,还有可能…...
公路边坡安全监测中智能化+定制化+全面守护的应用方案
面对公路边坡的安全挑战,我们如何精准施策,有效应对风险?特别是在强降雨等极端天气下,如何防范滑坡、崩塌、路面塌陷等灾害,确保行车安全?国信华源公路边坡安全监测解决方案,以智能化、定制化为…...
Arduino 驱动GY-271(HMC5883L)三轴磁场模块
Arduino 驱动GY-271(HMC5883L)三轴磁场模块 简介特征参数原理图寄存器通信测量步骤接线主要代码结果 简介 HMC5883L 是一种表面贴装的高集成模块,并带有数字接口的弱磁传感器芯片,应用于低成本罗盘和磁场的检测领域。HMC5883L 包…...
ImportError: cannot import name ‘einsum‘ from ‘einops‘
报错: from einops import einsum ImportError: cannot import name einsum from einops 测试代码: python -c "from einops import einsum" 解决方法: pip uninstall einops pip install einops Successfully installed ein…...
GitLab安装及使用
目录 一、安装 1.创建一个目录用来放rpm包 2.检查防火墙状态 3.安装下载好的rpm包 4.修改配置文件 5.重新加载配置 6.查看版本 7.查看服务器状态 8.重启服务器 9.输网址 二、GitLab的使用 1.创建空白项目 2.配置ssh 首先生成公钥: 查看公钥 把上面的…...
攻防世界web第二题unseping
这是题目 <?php highlight_file(__FILE__);class ease{private $method;private $args;function __construct($method, $args) {$this->method $method;$this->args $args;}function __destruct(){if (in_array($this->method, array("ping"))) {cal…...
Bitmap(BMP)图像信息验证
Bitmap BMP图像信息验证 参考文章例程目的一、Bitmap图像结构二、获取文件大小三、获取应用程序路径四、获取目录中所有内容(包括子目录)五、Bitmap图像信息验证六、主函数测试七、测试结果 参考文章 在Windows下C语言获取当前应用程序运行路径并获取指定目录下所有文件Bitmap…...
Faster R-CNN
文章目录 摘要Abstract1. 引言2. 框架2.1 RPN2.1.1 网络结构2.1.2 损失函数2.1.3 训练细节 2.2 训练过程 3. 创新点和不足3.1 创新点3.2 不足 参考总结 摘要 Faster R-CNN是针对Fast R-CNN缺点改进的目标检测模型。为了解决候选区域生成耗时长的问题,Faster R-CNN提…...
MySQL数据库锁
MySQL中读写不互斥(前提是没有使用串行化隔离级别),但是写写操作要互斥才行,MySQL中使用锁机制来实现写写互斥。 按照锁的粒度可以分为:全局锁、表锁、行锁以及其他位于二者之间的间隙锁。 全局锁 锁定整个数据库&…...
树莓派A+安装lnmp-第一步,安装mariadb
20:26 2024/12/27 第一件事情,当然是超频!!! raspi-config 4 Performance Options,选择P1 Overclock,可配置超频 不要贪心,选择900就可以!!! rootpia4:~#…...
C++:单例模式
创建自己的对象,同时确保对象的唯一性。 单例类只能有一个实例☞静态成员static☞静态成员 必须类外初始化 单例类必须自己创建自己的唯一实例 单例类必须给所有其他对象提供这一实例 静态成员类内部可以访问 构造函数私有化☞构造函数私有外部不能创建&#x…...
【数据结构】数据结构整体大纲
数据结构用来干什么的?很简单,存数据用的。 (这篇文章仅介绍数据结构的大纲,详细讲解放在后面的每一个章节中,逐个击破) 那为什么不直接使用数组、集合来存储呢 ——> 如果有成千上亿条数据呢ÿ…...
网页数据的解析提取之Beautiful Soup
前面博客介绍了正则表达式的相关用法,只是一旦正则表达式写得有问题,得到的结果就可能不是我们想要的了。而且每一个网页都有一定的特殊结构和层级关系,很多节点都用id或 class 作区分所以借助它们的结构和属性来提取不也可以吗? 本篇博客我…...
Ai写作人工智能官网模板源码
Mortal是响应式的Tailwind CSS 模板,适用于AI写作和文案智能生成网站。 可用于撰写博客内容、数字广告文案、技术写作、SEO内容、登陆页面文案、社交媒体内容、电子邮件营销、网站文案等。使用世界上流行的响应式CSS框架Tailwind CSS、HTML5、CSS3 和 Javascript构…...
VSCode 插件开发实战(七):插件支持了哪些事件,以及如何利用和监听这些事件
前言 VSCode 作为现代开发者的首选编辑器之一,其核心优势在于其高度可扩展性。通过自定义插件,开发者可以根据自己的需求对编辑器进行功能扩展和优化。在这些插件开发过程中,事件处理和监听机制尤为重要,它们允许插件在特定事件发…...
现货量化合约跟单系统开发策略指南
随着加密货币市场的日益发展,量化交易和合约跟单已经成为了投资者在市场中获取稳定收益的重要手段。现货量化合约跟单系统作为一种自动化交易工具,可以帮助用户自动执行交易策略,同时也能跟随成功的交易者进行复制交易,从而降低投…...
Flink的Watermark水位线详解
一、Flink的时间语义 Flink有如下三种时间语义: Flink的三种时间语义-CSDN博客 在实际应用中,一般会采用事件时间语义。而正如前面所说的,事件时间语义需要等窗口的数据全部到齐了,才能进行窗口计算。那么,什么时候数…...
香港 GPU 服务器托管引领 AI 创新,助力 AI 发展
在当今科技飞速发展的时代,中国人工智能市场呈现出蓬勃发展的态势,对高性能计算资源的需求日益增长,而香港 GPU 服务器托管服务凭借其卓越的优势,成为众多企业的首选,同时其三地灾备方案更是为企业数据安全和业务连续性…...
FFmpeg来从HTTP拉取流并实时推流到RTMP服务器
当使用FFmpeg来从HTTP拉取流并实时推流到RTMP服务器时,你可以使用以下命令: ffmpeg -i http://输入流地址 -c:v copy -c:a copy -f flv rtmp://RTMP服务器地址/应用名称/流名称 这是一个基本的命令示例,其中: - -i http://输入流地…...
vue 集成 webrtc-streamer 播放视频流 - 解决阿里云内外网访问视频流问题
资料: 史上最详细的webrtc-streamer访问摄像机视频流教程-CSDN博客 webrtc目录 前端集成 html文件夹里的webrtcstreamer.js,集成到前端,可以访问webrtc,转换rtsp为webrtc视频流,在前端video中播放 <videoref&quo…...
Spring创建异步线程池方式
在Java 11中,可以通过多种方式创建异步线程池,包括使用原生的ExecutorService和Spring的异步支持(如Async注解结合线程池)。以下是具体实现方式。 方式 1:使用原生ExecutorService Java 11 的ExecutorService提供灵活…...
《PHP MySQL 插入数据》
《PHP MySQL 插入数据》 介绍 PHP是一种广泛使用的服务器端脚本语言,而MySQL是一种流行的关系型数据库管理系统。在Web开发中,经常需要将用户输入的数据存储到数据库中。本文将详细介绍如何使用PHP和MySQL实现数据的插入操作。 环境准备 在开始之前&…...
2022博客之星年度总评选开始了
作者简介:陶然同学 专注于Java领域开发 熟练掌握Java、js等语言的“Hello World” CSDN原力计划作者、CSDN内容合伙人、Java领域优质作者、Java领域新星作者、51CTO专家、华为云专家、阿里云专家等 🎬 陶然同学🎥 由 陶然同学 原创&#…...
0055. shell命令--useradd
目录 55. shell命令--useradd 功能说明 语法格式 选项说明 选项 退出值 相关文件 /etc/passwd /etc/shadow /etc/group /etc/gshadow /etc/skel/ /etc/login.defs /etc/default/useradd 实践操作 注意事项 55. shell命令--useradd 功能说明 useradd 命令是 Lin…...
HTML5适配手机
要使 HTML5 网站适配手机设备,您可以遵循以下几个步骤和最佳实践: 1. 使用视口(Viewport) 在 HTML 文档的 <head> 部分添加视口元标签,以确保页面在移动设备上正确缩放和显示: <meta name"…...
网络安全 | 5G网络安全:未来无线通信的风险与对策
网络安全 | 5G网络安全:未来无线通信的风险与对策 一、前言二、5G 网络的技术特点2.1 超高速率与低延迟2.2 大容量连接与网络切片 三、5G 网络面临的安全风险3.1 网络架构安全风险3.2 设备终端安全风险3.3 应用场景安全风险3.4 用户隐私安全风险 四、5G 网络安全对策…...
Markov test笔记
补充知识 来源于数学之美第五章: 到了 19 世纪,概率论的发展从相对静止的随机变量的研究发展到随机变量的时间序列 ( s 1 , s 2 , s 3 , … ) (s_1, s_2, s_3, \dots) (s1,s2,s3,…),即随机过程(动态的)。这在…...
docker 搭建集群
准备3台机器: #dockermaster 192.168.31.150 sudo hostnamectl set-hostname dockermaster #初始化主节点 docker swarm init --advertise-addr 192.168.31.150 #查看集群是否搭建成功 docker node ls #dockernode1 192.168.31.151 sudo hostnamectl set-hostname …...
C# WPF读写STM32/GD32单片机Flash数据
1.安装jlink 下载你需要的Jlink版本 JLink-Windows-V792k-x86-64 JLink-Windows-V810k-x86-64 https://download.csdn.net/download/hmxm6/90178195 2.Visual Studio创建WPF项目 如果没有这个选项请看 https://blog.csdn.net/hmxm6/article/details/132914337 创建完…...
[图形渲染]【Unity Shader】【游戏开发】 Shader数学基础17-法线变换基础与应用
在计算机图形学中,法线(normal) 是表示表面方向的向量。它在光照、阴影、碰撞检测等领域有着重要作用。本文将介绍如何在模型变换过程中正确变换法线,确保其在光照计算中的正确性,特别是法线与顶点的变换问题。 1. 法线与切线的基本概念 法线(Normal Vector) 法线(或…...
MySQL外键类型与应用场景总结:优缺点一目了然
前言: MySQL的外键简介:在 MySQL 中,外键 (Foreign Key) 用于建立和强制表之间的关联,确保数据的一致性和完整性。外键的作用主要是限制和维护引用完整性 (Referential Integrity)。 主要体现在引用操作发生变化时的处理方式&…...
Axure10
如果还是不行就将字体图标安装在控制面板–字体下 打开原型了之后,icon没有 一定要将字体库放到–》控制面板\外观和个性化\字体 里面...
数据结构(单向循环链表)
循环单向链表 所谓的循环,指得是将链表末尾节点的后继指针指向头结点。比如,单向链表变成循环链表的示意 图如下所示: 循环链表的操作跟普通链表操作基本上是一致的,只要针对循环特性稍作修改即可。 sclist.h #ifndef __SCLIST_…...
springboot项目搭建
springboot搭建 问题描述不够清晰,无法提供具体的代码解决方案。"springboot搭" 这个表述不明确是要进行什么操作,比如搭建项目、搭建环境、搭建服务等。 如果你是想要创建一个基本的Spring Boot项目,可以使用Spring Initializr&…...
五模型对比!Transformer-GRU、Transformer、CNN-GRU、GRU、CNN五模型多变量时间序列预测
目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 光伏功率预测!五模型对比!Transformer-GRU、Transformer、CNN-GRU、GRU、CNN五模型多变量时间序列预测(Matlab2023b 多输入单输出) 1.程序已经调试好,替换数据集后,仅运…...
02-18.python入门基础一基础算法
(一)排序算法 简述: 在 Python 中,有多种常用的排序算法,下面为你详细介绍几种常见的排序算法及其原理、实现代码、时间复杂度以及稳定性等特点,并对比它们适用的场景。 冒泡排序(Bubble Sor…...
条款19 对共享资源使用std::shared_ptr
目录 一、std::shared_ptr 二、std::shared_ptr性能问题 三、control block的生成时机 四、std::shared_ptr可能存在的问题 五、使用this指针作为std::shared_ptr构造函数实参 六、std::shared_ptr不支持数组 一、std::shared_ptr<T> shared_ptr的内存模型如下图&…...
TCP-UDP调试工具推荐:Socket通信测试教程(附详细图解)
前言 在网络编程与应用开发中,调试始终是一项不可忽视的重要环节。尤其是在涉及TCP/IP、UDP等底层网络通信协议时,如何确保数据能够准确无误地在不同节点间传输,是许多开发者关注的核心问题。 调试的难点不仅在于定位连接建立、数据流控制及…...