Rust Turbofish 的由来
0x01 什么是 Turbofish
我们运行如下 Rust Snippet:
fn main() {let numbers: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];let even_numbers = numbers.into_iter().filter(|n| n % 2 == 0).collect();println!("{:?}", even_numbers);
}
不出意外,Rust 编译器一定会抛出错误
aggresss@traitx tmp % branch:[main]% cargo checkChecking tmp v0.1.0 (/tmp)
error[E0283]: type annotations needed--> tmp/src/main.rs:3:9|
3 | let even_numbers = numbers.into_iter().filter(|n| n % 2 == 0).collect();| ^^^^^^^^^^^^ ------- type must be known at this point|= note: cannot satisfy `_: FromIterator<i32>`
note: required by a bound in `collect`--> /Users/aggresss/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2050:19|
2050 | fn collect<B: FromIterator<Self::Item>>(self) -> B| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Iterator::collect`
help: consider giving `even_numbers` an explicit type|
3 | let even_numbers: Vec<_> = numbers.into_iter().filter(|n| n % 2 == 0).collect();| ++++++++For more information about this error, try `rustc --explain E0283`.
error: could not compile `tmp` (bin "tmp") due to 1 previous error
上面的错误可以通过两种方式解决
-
第一种方式在 even_numbers 变量声明时声明类型:
let even_numbers: Vec<_> = numbers.into_iter().filter(|n| n % 2 == 0).collect();
-
第二种方式使用 Turbofish 语法,在泛型函数后面加入
::<>
:let even_numbers = numbers.into_iter().filter(|n| n % 2 == 0).collect::<Vec<_>>();
泛型在编译的过程中要被实例化,大多数情况下,具体类型是基于 Hindley-Milner 理论的类型推断,但是在一些特殊情况下,我们需要显示声明类型来帮助编译器排除歧义,这也是 Turbofish 存在的原因。
在使用泛型的过程中,其他语言也会遇到类似的问题,例如 C++ 中使用 ident<T>
,或者 Golang 中使用 ident[T]
,而 Rust 中确使用 ident::<T>
,多了两个冒号(double colon),第一次看到确实觉得有点多余,通过考古在 reddit 上看到 Anna Harren (u/deadstone) 的解释后理解了这样设计的初衷,即可以降低编译器的语法解析难度。
这是一种从语言设计者角度的 Tradeoff,所以语言的使用者多少会有一些疑问或抱怨,在 Rust 社区中确实也会时常听到一些相关的声音,但是当知道了 Turbofish 语法由来的故事后,我已经开始喜欢 ::<>
这个符号。
0x02 Turbofish 的由来
在 2015 年的时候,Anna Harren 第一次提出使用 ::<>
来辅助编译器进行类型判断,同时给它起了一个很有意思的名字 –– TURBOFISH,很快这个名字也被 Rust 官方所采纳,这个符号确实挺像一条加速的鱼,还有人做了一个页面 https://turbo.fish/。不幸的是在 2021 年 Anna Harren 因患癌症离开了这个世界,Rust 1.55.0 的 Release Note 特别提到了她,并将这个版本作为对 Anna Harren 的纪念。
可能开源社区的魅力就在于对多样性的包容,Rust 社区争吵不断,但更容易诞生有趣的事物,毕竟这个世界有那么多有趣的灵魂。
0x03 Furthermore
有一个彩蛋发现,将 Turbofish 符号 ::<>
倒过来, 即 <>::
,Rust 在 Disambiguating Function Calls 中使用 ::
作为 namespace qualifier,同时使用 <>::
作为路径中存在类型混淆时的显示声明,例如:
fn main() {let s = "Hello, World!";let string = <&str as Into<String>>::into(&s);println!("{}", string);
}
这种方法早期被叫做 UFCS (Universal Function Call Syntax),于此同时,使用 Turbofish 也可以反向解决上面的问题:
fn main() {let s = "Hello, World!";let string = Into::<String>::into(s);println!("{}", string);
}
从优雅对称的角度看,我还是支持 Turbofish 仍然是 Turbofish。
0x04 Reference
- https://www.reddit.com/r/rust/comments/3fimgp/comment/ctozkd0/
- https://github.com/rust-lang/rust/blob/master/tests/ui/parser/bastion-of-the-turbofish.rs
- https://foundation.rust-lang.org/news/member-spotlight-turbofish/
- https://turbo.fish/
- https://github.com/jplatte/turbo.fish
- https://blog.rust-lang.org/2021/09/09/Rust-1.55.0.html#dedication
- https://matematikaadit.github.io/posts/rust-turbofish.html
- https://www.reddit.com/r/rust/comments/v4rir6/turbofish_why/
- https://techblog.tonsser.com/posts/what-is-rusts-turbofish
- https://doc.rust-lang.org/reference/expressions/call-expr.html
相关文章:
Rust Turbofish 的由来
0x01 什么是 Turbofish 我们运行如下 Rust Snippet: fn main() {let numbers: Vec<i32> vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];let even_numbers numbers.into_iter().filter(|n| n % 2 0).collect();println!("{:?}", even_numbers); }不出意…...
2.外卖点餐系统(Java项目 springboot)
目录 0.系统的受众说明 1.系统功能设计 2.系统结构设计 3.数据库设计 3.1实体ER图 3.2数据表 4.系统实现 4.1用户功能模块 4.2管理员功能模块 4.3商家功能模块 4.4用户前台功能模块 4.5骑手功能模块 5.相关说明 新鲜运行起来的项目:如需要源码数据库…...
Universal Thresholdizer:将多种密码学原语门限化
参考文献: [LS90] Lapidot D, Shamir A. Publicly verifiable non-interactive zero-knowledge proofs[C]//Advances in Cryptology-CRYPTO’90: Proceedings 10. Springer Berlin Heidelberg, 1991: 353-365.[Shoup00] Shoup V. Practical threshold signatures[C…...
【UE5学习笔记】编辑及运行界面:关闭眼部识别(自动曝光)
自动曝光,也就是走进一个黑暗的环境,画面会逐渐变量,以模拟人眼进入黑暗空间时瞳孔放大,进光量增加的一种真实视觉感受: 制作过程中是否关闭自动曝光,取决于游戏的性质,但是个人认为,…...
未来科技的前沿:深入探讨人工智能的进展、机器学习技术和未来趋势
文章目录 一、人工智能的定义和概述1. 人工智能的基本概念2. 人工智能的发展历史 二、技术深入:机器学习、深度学习和神经网络1. 机器学习2. 深度学习3. 神经网络 三、人工智能的主要目标和功能1. 自动化和效率提升2. 决策支持和风险管理3. 个性化服务和预测未来 本…...
3-qt综合实例-贪吃蛇的游戏程序
引言: 如题,本次实践课程主要讲解贪吃蛇游戏程序。 qt贪吃蛇项目内容: 一、功能需求 二、界面设计 各组件使用: 对象名 类 说明 Widget QWidge 主窗体 btnRank QPushButton 排行榜-按钮 groupBox QGroupBox 难…...
QGraphicsView实现简易地图12『平移与偏移』
前文链接:QGraphicsView实现简易地图11『指定层级-定位坐标』 提供地图平移与偏移功能。地图平移是指将地图的中心点更改为给定的点,即移动地图到指定位置。地图偏移是指将当前视口内的地图向上/下/左/右/进行微调,这里偏移视口宽/高的四分之…...
深入探索 Vue 中的 createVNode 与 resolveComponent
在 Vue 开发中,createVNode和resolveComponent是两个至关重要的工具,它们为我们提供了强大的能力来灵活地创建和操控组件。 一、首先,让我们深入了解一下createVNode。 这是一个用于创建虚拟节点的关键函数,通过它,我…...
【记录42】centos 7.6安装nginx教程详细教程
环境:腾讯云centos7.6 需求:安装nginx-1.24.0 1. 切入home文件 cd home 2. 创建nginx文件 mkdir nginx 3. 切入nginx文件 cd nginx 4. 下载nginx安装包 wget https://nginx.org/download/nginx-1.24.0.tar.gz 5. 解压安装包 tar -zxvf nginx-1.24.0.…...
C语言程序设计(不熟悉的点)
一、switch多路分支语句 二、条件表达式 三、循环 for循环: for循环的三个表达式不是必须的,第一个表达式之前声明过,可以不写,第三个表达式可以放在循环体里面;第二个表达式可以不写,为死循环。 空循环…...
DAO是什么?有什么用途?
DAO(Decentralized Autonomous Organization,去中心化自治组织)是一种基于区块链技术的组织形式,它没有中央管理层,而是通过智能合约和区块链上的代码来运作。DAO 的决策过程是透明的,通常由组织的成员通过…...
Socket学习记录
本次学习Socket的编程开发,该技术在一些通讯软件,比如说微信,QQ等有广泛应用。 网络结构 这些都是计算机网络中的内容,我们在这里简单回顾一下: UDP(User Datagram Protocol):用户数据报协议;TCP(Transmission Contr…...
黑马 - websocket搭建在线聊天室
这里写自定义目录标题 一、消息推送常见方式二、websocket 是什么?三、websocket api的介绍1、客户端 (浏览器)2、服务端api 四、实现在线聊天室1、需求2、聊天室流程分析3、消息格式4、代码实现 一、消息推送常见方式 1、轮训方式 2、SSE…...
【每日力扣】543. 二叉树的直径与101. 对称二叉树
🔥 个人主页: 黑洞晓威 😀你不必等到非常厉害,才敢开始,你需要开始,才会变的非常厉害 543. 二叉树的直径 给你一棵二叉树的根节点,返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的…...
【linux】——日志分析
1. 日志文件 1.1 日志文件的分类 日志文件: 是用于记录Linux系统中各种运行消息的文件,相当于Linux主机的“日记". 日志文件对于诊断和解决系统中的问题很有帮助,系统一旦出现问题时及时分析日志就会“有据可查”。此外。当主机遭受攻…...
【intro】GraphSAGE
论文 https://arxiv.org/pdf/1706.02216 abstract 大图中节点的低维embedding已经被证明在各种预测任务中非常有用,然而,大多数现有的方法要求在embedding训练期间图中的所有节点都存在;这些先前的方法属于直推式(transductive)…...
管理能力学习笔记九:授权的常见误区和如何有效授权
授权的常见误区 误区一:随意授权 管理者在授权工作时,需要依据下属的能力、经验、意愿问最自己:这项工作适合授权给Ta做吗?如果没有,可以通过哪些方法进行培训呢? 误区二:缺乏信任 心理暗示…...
第21天 反射
反射概述 想象一下,你在一个房间里边,但你看不见自己,也不知道自己是谁。这时候你面前有一个镜子,你可以通过镜子的反射来观察自己。反射就像这面镜子。它让你能够检查、分析、修改Java中的对象、类、方法等 使用情况࿱…...
多链路聚合设备是什么
多链路聚合设备属于通信指挥装备。 乾元通多链路聚合设备,它能够将多个网络链路聚合成一个逻辑链路,以实现高速、稳定、可靠的数据传输。多链路聚合设备的核心技术包括链路聚合、负载均衡、故障切换等,能够智能管理和优化利用不同网络链路&a…...
基于springboot+vue+Mysql的自习室预订系统
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...
解决后端ID传到前端时被截断,末尾显示00
问题原因: Java后端Long类型的取值和前端Number类型取值范围不一样。 解决方案: 将id字段进行json序列化时转为字符串。 JsonSerialize(using ToStringSerializer.class) private Long id;...
Transformer中的数据输入构造
文章目录 1. 文本内容2. 字典构造2.1 定义一个类用于字典构造2.2 拆分文本2.3 构造结果 3. 完整代码 1. 文本内容 假如我们有如下一段文本内容: Optics It is the branch of physics that studies the behaviour and properties of light . Optical Science 这段…...
完美实现vue3异步加载组件
经过几个小时的努力,终于实现了,根据组件名异常加载组件,直接上代码,网上的很多代码方都有坑,先贴出比较坑的代码: <template><view class"main"> <view class"tops"…...
点云成图原理
点成图(Point Cloud)是指由一组离散的点构成的图形,它们在空间中没有任何连接关系。点成图通常是由激光雷达、相机或其他传感器获取的三维数据,用于表示现实世界中的物体或场景。 三角成图(Triangulation)…...
如何将jsp项目转成springboot项目
昨天说过,springboot推荐使用Thymeleaf作为前后端渲染的模板引擎,为什么推荐用Thymeleaf呢,有以下几个原因: 动静结合:Thymeleaf支持HTML原型,允许在HTML标签中增加额外的属性来实现模板与数据的结合。这样…...
C语言:环形链表
1.例子1:环形链表 142. 环形链表 II - 力扣(LeetCode) 思路:我们先定义两个变量slow和fast,slow每次走一步,fast每次走两步,如果链表是环形链表,那么必定存在fast不会走到链表的最后…...
typescript综合练习1(展开音乐播放列表)
Playlist Soundness What’s up, friend?! I’m so pumped you’re joining us. We’ve got a sick project we could totally use your help on! See, someone’s giving us amazing recommendations for songs to play. But they’re not just coming in as songs. Someti…...
零基础入门学习Python第二阶02面向对象,迭代器生成器,并发编程
Python语言进阶 面向对象相关知识 三大支柱:封装、继承、多态 例子:工资结算系统。 """月薪结算系统 - 部门经理每月15000 程序员每小时200 销售员1800底薪加销售额5%提成"""from abc import ABCMeta, abstractmethodcl…...
Unity | Shader基础知识(第十三集:编写内置着色器阶段总结和表面着色器的补充介绍)
目录 前言 一、表面着色器的补充介绍 二、案例viewDir详解 1.viewDir是什么 2.viewDir的作用 3.使用viewDir写shader 前言 注意观察的小伙伴会发现,这组教程前半部分我们在编写着色器的时候,用的是顶点着色器和片元着色器的组合。 SubShader{CGPRO…...
JavaScript map对象/set对象详解
文章目录 一、map对象二、map对象应用场景1. 数组元素转换2. 对象数组的属性提取或转换3. 数组元素的复杂转换4. 与其他数组方法结合使用5. 与异步操作结合(使用 Promise)6. 生成新的数据结构7. 数学和统计计算 三、set对象1. 基本使用2. 特性3. 注意事项…...
天津平台网站建设设计/seo网站营销推广公司
[传送门] 问题: 树状数组: 单点修改,区间查询 感觉 还是挺简单的嘛 就一个lowbit CODE #include <bits/stdc.h> using namespace std; const int N 5e510; typedef long long ll; ll a[N],c[N]; ll n,m;ll lowbit(ll x) {return x&(-x); } void updata(ll i,…...
深圳服务网站设计哪家公司好/推广平台哪个效果最好
题库来源:安全生产模拟考试一点通公众号小程序 2022化工自动化控制仪表题库系化工自动化控制仪表试卷新版教材大纲题库!2022年化工自动化控制仪表复训题库及在线模拟考试根据化工自动化控制仪表考试大纲。化工自动化控制仪表考试模拟题通过安全生产模拟…...
凡科互动小游戏怎么刷高分/线下课程seo
条件运算符(?:)是C语言中唯一的一个三目运算符,它是对第一个表达式作真/假检测,然后根据结果返回另外两个表达式中的一个。 <表达式1>?<表达式2>:<表达式3> 在运算中,首先对第一个表达式进行检验,如果为真&am…...
wordpress 插件安装失败/湖南靠谱seo优化报价
项目背景和意义 目的:本课题主要目标是设计并能够实现一个基于web网页的电子书阅读系统,整个网站项目使用了B/S架构,基于python的Django框架下开发;管理员通过后台录入信息、管理信息,设置网站信息,管理会员…...
购物网站前端浮动特效怎么做/百度快速收录教程
本文将要为您介绍的是深入理解perf报告中的swapper进程,教程操作步骤:一、前言1、在perf监控进程的系统调用时,会出现大量swapper进程2、官方描述该进程是当CPU上没有其他任务运行时,就会执行swapper。换句话说swapper意味着CPU啥事也没干,跑…...
岳阳网站建设哪里有/可以免费发布广告的平台有哪些
大家好,欢迎来到《刺激实战教室》,我是你们的老朋友刺激哥。不知道,有没有小伙伴像刺激哥一样,起了个大早,就为了看《和平精英》更新了什么内容。在介绍本期更新之前,刺激哥想吐槽一下《和平精英》体验服。…...