- 博客(46)
- 收藏
- 关注
原创 【openGL入门(一)】
朴素的讲,VAO EBO 都服务于VBO,VBO是真正的cpu 与gpu之间的数据中介,有了顶点数据,也告知了gpu如何解析数据,后续该通过渲染管线实际操作,将想要绘制的数据绘制到窗口中。
2024-12-09 19:34:00
798
原创 【Rust WebAssembly 入门实操遇到的问题】
WebAssembly(简称Wasm)是一种基于堆栈的虚拟机的二进制指令格式。Wasm 被设计为编程语言的可移植编译目标,支持在 Web 上部署客户端和服务器应用程序。简而言之,WebAssembly(wasm)是一种可以执行在堆栈虚拟机的二进制可执行指令集(所以在你编译后将看到后缀为wasm的二进制文件,这种文件可以运行在Wasm Runtime 上),一般的,市面上常见的浏览器均支持wasm Runtime。
2024-12-03 15:22:18
1326
原创 【DDS之fastdds浅析】
DDS(Data Distribution Service)数据分发服务在人工智能和自动驾驶商业方面有很多应用,DDS 都遵守RTPS传输协议,常见的DDS有OpenDDS,fastDDS,RTIDDS,本土的有MDC,Rust版本的dds有RustDDS等。FastDDS因其开源且稳定性和效率更优而被广泛使用,同时它还是Ros2的default middleware,本文以FastDDS为例浅析DDS的组成部分以及其作用,并通过源码示例概述使用方式。DDS 是数据分发服务,是以数据为中心的通信协议。
2024-11-26 16:46:24
1035
原创 【Rust中的切片Slice】
切片对于使用过Go的开发者并不陌生,其定义是一块内存视图,用指针和长度来表示。Rust中切片是引用类型,所以它并不具备所有权。关于切片对于如Vec也是一样的,不在展开赘述。
2024-11-25 09:31:46
851
原创 【Rust Iterator 之 fold,map,filter,for_each】
在Iterator一文中,我们提到过Iterator时惰性的,也就是当我们将容器转换成迭代器时不会产生任何的迭代行为,所以在使用时开发者还需要将迭代器与消费者适配器共同使用。在实际开发中会遇到各种各样的需求,熟练掌握method并理解其中的意义和作用,可以让我们更加rusty。“积跬步,行万里。
2024-11-24 18:46:03
940
原创 【关于Rust HashMap使用的一点思考】
在日常开发中,容器在各种语言中通常作为存储短时或从属某类的数据集合,而集合数据尤其是在一个事务周期内的值经常会发生改变,对于最常用的 vector 在rust中来说很简单使用Index获取value即可,因为他被实现了IndexMut,而Rust中带有Vec前缀的容器组都实现了IndexMut Trait,这也就说明,这些容器在日常使用时和C++,C#,等语言的使用方式基本雷同。将新值直接插入map,当开发者做统计时,如统计一个数组不同元素出现的次数,这样写总归不如"map[k] = v;
2024-11-24 11:37:51
528
原创 【Unity ShaderGraph实现流体效果之Node入门(二)】
在(一)中讨论了一部分在制作流体效果时使用的Node,本章继续将剩余部分补充。
2024-11-21 09:21:02
457
原创 【Unity ShaderGraph实现流体效果之Function入门】
Unity 提供的Shader Graph在很大程度上简化了开发者对于编写Shader的工作,只需要拖拽即可完成一个视觉效果的制作,使用ShaderGraph的前提一个是了解到shaderGraph如何操作,二是理解每一个Shader Graph Node 的作用,才能组合出想要的效果,本文不针对操作进行必要讲解,仅针对在实现流体效果时用到的Shader Graph Node进行解释和整理。基本项会分为两篇文章分享,最后的Graph可用package会上传到指定位置,仅供参考。
2024-11-20 15:30:59
505
原创 Rust中的静态派发与动态派发
在CPP语言中,为了代码的灵活性和复用性,模板和继承中的父类指针指向子类引用的实现方式被开发者喜欢,对于Rust来说,便是泛型,特征约束和dyn关键字。他们的目的类似,只不过在特定的语言范围内使用方式不大相同。在rust泛型与特征一文中,我们讨论了Box< dyn Trait >的写法,本文做进一步的补充说明,这里关注于代码举例与细节对比。
2024-11-20 08:56:25
1139
原创 【遵守孤儿规则的External trait pattern】
一般的,开发者在使用rust为类型实现trait时,通常有两种路径,一种是为内部类型实现外部trait(impl External Trait for Internal Type),一种是为外部类型实现内部trait(impl Internal Trait for External Type),不同的实现路径依赖于具体的需要。孤儿规则,Rust限制了开发者,在实现trait时,至少类型和trait有一个在当前实现的crate内,方才可以实现trait,否则将会报错,既。实现扩展,如过滤重复Item等等。
2024-11-19 10:28:55
1207
原创 【Unity Dots之Ecs原理分析(无入门代码示例)】
Unity 的ECS 是Unity DOTS的组成部分,是编码的重要部分,DOTs的其他方面还包含Brust Compiler等等。结构化更改既在对Entity与其组件的更新过程中,对Chunk中的存储数据进行了删除,插入,以及对ShareComponent 修改了值。
2024-11-18 20:39:53
1329
原创 【Rust中的策略模式实现】
策略模式就是针对不同的需求使用不同的策略。具体的实例如在生成报告时,需要不同的格式,如json,html等等,出发点是一样的,开发者的需求导向是结果报告,而具体的,策略就是不同的报告格式。抽象成代码实现思路就是,开发者需要定义一个统一的接口(在rust中是trait),在使用者调用时触发,而针对不同的格式,开发者需要定义不同的实现,也就是针对接口实现不同的代码。在调用时,调用方需要直到不同实现之间的区别,但是无需关注具体的实现,如同集成测试一般,拿到结果即可。
2024-11-17 11:05:45
578
原创 【Rust设计模式之新类型模式】
类型驱动一节中有提及过新类型模式,新类型模式是类型驱动的一种方式,主要是通过新类型的封装让使用者不用考虑原来类型的细节,也保证了privacy,从而避免不必要的bug,如开发者的误操作将输入性数据修改等等。新类型模式通常情况下直接使用元组结构体将本来的类型转换为一目了然的名称,借助元组结构体内部元素不可见性,保护内部元素不被修改,同时也降低了开发者的思考难度,需要注意的是,正是因为开发者借助了元组结构体的内部不可见性,在实现时不要再将内部元素设置为pub否则也就失去了封装的意义。
2024-11-15 08:26:44
740
原创 【Rust中的项目管理】
在开发者进行项目立项并逐步开发时,尤为重要的是项目结构和各个模块的管理,在C++中,通常我们结合文件夹以及namespace和头文件的共同作用下将项目结构变得合理,Rust为开发者提供了一整套管理体系如Package,Crates,Module &use ,Path,通过这些特性来共同管理Rust项目,开合自如。
2024-11-14 19:10:46
2401
原创 【Rust项目中的unit test & integration test】
单元测试(unit test),即以开发者的角度,与主程序代码关系密切的测试,简单来说,单元测试一般包含在源代码文件夹中,通过对程序代码内的函数单元直接调用,在通过Err/panic/assert等的判断方式判定结果,使用方式如开发者的使用方式一般。集成测试(intergration test),既以用户的角度,通常在源代码之外的文件夹内,调用pub函数,通过函数行为产生的结果判断正确性,举个例子,如果开发者实现的是一个库,集成测试就更加接近库使用方的调用方式。
2024-11-13 11:21:50
1385
原创 【Rust类型驱动开发 Type Driven Development】
type-diven development,即将开发者需要的逻辑约束条件编码到类型系统中,举个例子,一般业务逻辑下开发者通常需要检查输入的正确性,一般情况下开发者的思维惯性会在调用function的内部做一些逻辑判断,比如字符串长度是否符合条件,格式是否符合如人名,邮箱地址等等。类型驱动开发是将此类检查放在形成某一种类型的时候完成,即如果逻辑不通则不会形成需要的类型,同样的,类型驱动开发也具备一定的封装性,保证开发者不会因为误用而破坏流程的安全性和产生一些垃圾数据。
2024-11-11 14:54:42
684
原创 【Rust.Crate之tracing 诊断系统】
日志对于每一个开发者来说并不陌生,开发者通常希望在程序代码中的一些需要做记录的地方加上日志,亦或在调试期间加的打印,随着需求的展开和经验的不断丰富,单纯的日志往往无法让开发者第一时间定位到问题,一般的,日志记录都是文本格式,且针对特定的数据并没有一个舒适的格式便于人类阅读,即便有时间戳等的信息,没有上下文的记录,开发者依然需要还原现场才能够排查到具体的问题原因,这对于快速迭代的日常开发和服务器线上问题的解决并不友好。
2024-11-08 17:09:18
1272
原创 【Rust设计模式之Fold模式】
如Rust Collection中的fold方法,是消耗迭代器适配器,将闭包应用于每一个元素,并将结果返回一样。Fold模式的中心思想也是如此,将元素折叠处理,最终计算出新的元素。而我们自己实现的Fold模式,一般用于映射数据结构,不同于面向对象的原地修改,由于Rust的引用和借用以及不可变性,生成新的结构从而替代老的结构调理更为清晰。总结:通常来说只有我们在自己编写一些数据结构的时候方才用得到这种fold模式,一般的业务逻辑相对的较少能够涉及到此,不过多懂一些也是极好的~“万全之计便是即刻行动”
2024-11-08 07:59:59
713
原创 【Rust设计模式之建造者模式】
即将结构体属性方法与构建解离,使用专门的builder进行建造,说白了就是new和其他的方法分开,集中处理更方便。("{:?
2024-11-07 16:39:01
555
原创 【Rust实现命令模式】
命令模式,即通过统一接口,如C#interface,亦或C++中的抽象类的=0方法,通过定义统一的接口,在定义不同的对象,为之接口实现具体的方法逻辑,再通过统一的管理类,将其存储在容器中如List或Deque等,在真正执行的时候按照顺序依次执行接口定义的方法就像执行命令一样。命令模式较为常用,尤其实在后端开发中,了解掌握命令模式对服务器框架源码理解也有好处,模式不是必选项,而是锦上添花。“我们从来都不清楚选择正确与否,只是努力的将选择变得正确.”
2024-11-06 10:36:10
692
原创 【Rust Crate之Actix Web(一)】
Actix Web 作为一个服务器框架,非常适合于搭建小型http服务器,方便快捷,它支持Http/1,Http2,TLS,尽管他也支持了Websocket,但在此不予讨论。Actix Web 易用性高,性能出众,如果开发者想在生产环境中使用Rust做Http Server,其是值得一选的,在整体的开发框架中,State同步,提取和Connfigure 以及Handler的 布局设计是重要的。“不论我们接受与否,一个不确定的时代已经到来”
2024-11-06 09:00:05
1309
原创 【Rust中的迭代器】
迭代是指,在一个过程中反复重复,不断推进。在计算机领域,迭代是重复执行某一个过程的方法,每一次执行都基于上一次执行的结果。迭代器用于接入和迭代数据结构中的元素,通过"指向"他们,在几乎所有编程语言中,迭代器的功效均是如此。迭代器可定制化,通常用于数据结构的迭代遍历,有很多方便的方法使用用以实现不同的目的,可以参考rust std.“我们都无法确定选择是否正确,只是努力把选择变得正确.”
2024-11-05 09:43:01
1169
原创 【rust中的闭包】
简而言之,闭包就是可以直接访问其外部作用域的函数内部匿名函数(有点狭隘,不过大部分如此)。如果你只想调用一次,用Fnonce,如果你想改变用FnMut,如果你想在多线程中使用且不改变用Fn.“我们都无法确定选择是否正确,只是努力把选择变得正确.”
2024-11-04 11:00:48
1299
原创 【Rust中的错误处理】
对于程序来说,一般可将错误分解为两大类,一类是因外部输入或调用方式有问题而产生的错误,一类是程序编写出现的错误问题,前者多半不会给程序带来极端的问题,而后者很有可能造成程序的崩溃等,所以编程时需要进行正确地错误处理。C++/C#均有各自的错误处理方法,有各自的error库,并有异常处理机制,不过这都需要人为“注意”,也就是说如果你忽略了错误处理,其编译器并不会提示你这是有问题的,panic,Result,unwrap,expect
2024-11-01 09:21:38
878
原创 【Rust标准库中的convert(AsRef,From,Into,TryFrom,TryInto)】
Rust中的转换,不仅仅使用方便,更重要的是可以告知阅读者我们在做什么,Asref,From,Into,TryFrom,TryInto
2024-10-31 11:02:22
1491
原创 【Rust中的序列化:Serde(一)】
序列化指的是将定义的结构化数据转换成更容易存储和或传输的形式,如字节流。而反序列化则是将如流式数据重新恢复成本来的样子,方便开发者解析和处理逻辑。通常情况下序列化反序列化使用在网络通信上。如我们熟知的protobuf等。注意到,在反序列化中引入了一个生命周期【'de】,一般情况下,我们常见的生命周期要么是【'static】要么是单字符【`a】来看看官方给出的解释:也就是说,这个因为Rust的生命周期规则,Rust可以安全高效的使用零Copy反序列化方案,而这在其他语言中几乎必然是不安全的。
2024-10-30 12:04:45
1583
原创 【Rust中的容器(二)】
在Rust中的容器(一)中,列举了Rust中的容器以及详聊了vector和Hashmap,本章将展示后续提及的容器用法。双端队列:VecDeque链表:LinkedList映射:BtreeMap集合:HashSet,BtreeSet其他:BinaryHeap。
2024-10-29 14:11:38
466
原创 【Rust中的容器(一)】
容器即将一系列具有相同特征的数据存储在一起。在编程过程中,开发者使用到的容器种类、原理以及使用方式基本相同。上述是Rust中最最常用的两个容器的基本原理概述和使用方法和注意事项,后续会更新未说明的剩余的容器的使用方法和原理概述。如有勘误,敬请指出。
2024-10-29 09:11:25
1065
原创 【Rust中的元组结构体】
结构体和元组的概念C++,C# 以及其他的语言基本一致,且特征也都接近,简而言之,结构体每一个字段都有名字,且类型根据需要自己设置,而元组没有字段名字,访问时需要使用".0" “.1” ".n"等介于元组和结构体之间的数据类型,有名字,没有字段名,适合在一些其外部名称即能够表达出类型具体含义,而字段仅仅是值得保存,并且可为其实现impl。age : u16,.........这样的写法既表达了设计上的意图,又简化了写法。
2024-10-28 18:29:51
453
原创 【Rust中的智能指针】
传统的指针,如C++中的裸指针,需要开发者自己申请和释放,如果开发者在使用过程中疏漏了回收,将会造成内存泄漏,在部署实施时也会有oom的风险,智能指针即是为了解决这类问题而出现的,老生常谈的shared_ptr,unique_ptr,weak_ptr等,都是通过设计使得代码自动管理回收堆上的内存,提高代码的健壮性和方便性。Rust由于其严格的安全性和所有权机制,除unsafe写法外,所有的堆内存都是通过语言特性管理的。
2024-10-28 10:16:40
915
原创 【Rust中的所有权(引用与借用)】
所有权是指所有权人依法对自己的财产享有的占有使用收益和处分的权利,所有权是Rust一系列管理内存的规则。通过这两组定义可以更通俗的理解到什么是rust的所有权,Rust即是“所有权人”,程序内存即是Rust的“财产”,Rust对内存独享的管理能力即是对其财产进行占有和使用出借等的权力。这里要特别强调的是,真正管理内存的是Rust内存规则本身,而不是具体某一个变量或载体,而Rust中的各种针对内存的写法规则也都是为了匹配Rust的内存处置规则。
2024-10-26 09:54:07
1047
原创 【Rust中的泛型与特征(二)】
在Rust中的泛型与特征(一)中,我们整理了rust泛型,特征trait,特征约束,以及与其他语言比较下的异同,本文重点结合前述知识点,与C++语言特性相比较,方便理解,重点在Rust的特征对象Rust中的泛型与特征(一)特征对象指向实现了某种特征的类型的实例,其映射关系存储在一张表中,在运行时可以通过特征对象找到特定的调用方法。同样先看看官方给我们的解释:结合示例,我将把官方提到的Animal在翻译时全都替换成Noise。
2024-10-25 15:02:44
990
原创 【Rust中的泛型与特征(一)】
泛型的本质是类型的参数化,允许在定义类、接口、方法时使用类型形参,当使用时指定具体类型,所有使用该泛型参数的地方都被统一化,保证类型一致。
2024-10-25 09:56:27
944
原创 【Rust中的生命周期】
Rust中的生命周期就像泛型一样,需要在函数上也标注上生命周期,这并不代表函数的生命周期,而是通过此标识符告知编译器,本函数手动。形如【T : 'a】,【'b : 'a】,表达的即T or b的作用域范围 >= a;【'a】意味着,开发者应当意识到,以引用形式传出的返回值的生命周期不应大于x,y 中较小生命周期范围。rust生命周期的写法与其泛型编程中的泛型类型写法类似,也可以对比C++中的模板写法。随着Rust的升级发展,这样的写法已经几乎不需要人为编写,编译器会自行推导。,并不是,编译器依然无法判断。
2024-10-24 09:20:11
1077
原创 【Rust中的异步编程】
rust中的异步模型,实际上是使用future(能产出值的异步计算),通过轮询,挂起,唤醒,执行等操作来实现异步,runtime依赖tokio。Tokio是一个Rust 异步运行时库,底层基于epoll/kqueue这样的跨平台多路IO复用以及event loop,目前正在支持io_uring。其线程会执行task,可以充分利用多核,而Task 线程是Rust基于Future抽象出的一种绿色线程,因为不需要预先分配多余的栈内存,可以创建大量的Task,很适合做IO密集型应用。fn poll(
2024-10-23 10:10:32
1398
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人