Rust-定义泛型结构

既然有泛型函数当然少不了泛型结构

struct S1<T1, T2> {
   n1: T1,
   n2: T2,
}

let s = S {n1:957, n2:996.1}

第一句语法宣告了两个型别T1和T2参数化的泛型结构S1,第一个字段n1为T1第二字段n2为T2

第二句语法n1字段的参数隐式的替换成i32,n2字段的参数隐式替换成f64

也可以使用泛型元组结构

struct SE<T1, T2> (T1, T2)

let se = SE (957, 996.1)

泛型机制

通过下面程序码来理解编译泛型机制概念

fn swap<T1, T2>(p1: T1, p2: T2) -> (T2, T1) {
    return (p2, p1);
}

let x = swap(5i16, 9u16);
let y = swap(6f32, true);

println!("{:?} {:?}", x, y);

输出
(9, 5) (true, 6.0)

第一阶段编译器会扫描程序码并且每次找到泛型函式宣告(swap)时,它在资料结构中加载该函式内部表示形式检查泛型程序码是否有语法错误

第二阶段编译器再次扫描程序码在每次遇到泛型函式调用时,编译器都会检查此类用法与泛型宣告的相应内部表示关联,在确认後再其资料结构中加载这种对应关系

第三阶段再将扫描所有泛型函式调用,对於每个泛型函式调用者都定义每个泛型参数的具体型别,这种具体型别可以是在用法中显式的或者如上面范例一样用推断出来的

在确定替换泛型参数的具体型别之後都会产生泛型函式的具体版本对应程序码如下

fn swap_i16_u16(p1: i16, p2: u16) -> (u16, i16) {
    return (p2, p1);
}

fn swap_f32_bool(p1: f32, p2: bool) -> (f32, bool) {
    return (p2, p1);
}

let x = swap_i16_u16(5i16, 9u16);
let y = swap_f32_bool(6f32, true);

println!("{:?} {:?}", x, y);

泛型编译有几个特点

  • 与非泛型程序码相比多阶段编译相对较慢一些
  • 生成的程序码针对每个特定的调用进行高度优化,它完成使用调用者使用的型别无须进行转换因此优化了运行时性能
  • 泛型函式如果执行很多具有不同型别参数的调用,则产生大量的机器代码,最好不要再单个函式调用太多型别会给CPU缓存造成负担

几种流行的泛型语言的代价
Slow Compiler: c++/rust
Slow Performance: java/scala
Slow Programmer: go1


<<:  @Day28 | C# WixToolset + WPF 帅到不行的安装包 [改版本号码却跳出旧版本]

>>:  Day.20 从零开始 - 实务需求学SQL_1

Day01 从零开始学React

前言 因为是第一次挑战铁人赛,参赛组别是自我挑战组,所以不想给自己太大压力,期许只要能完成30天不断...

[iT铁人赛Day28]练习题(7)

第二十八天了,讲到练习题第七题 不知不觉已经快结束了,因为篇幅的关系,所以可能无法说完全部的练习题 ...

Day14 Redis应用实战-Hash操作

Redis 资料型态Hash Hash是用来储存多组栏位值,可以是数字或字串.使用者可以对值进行操作...

【Day 01】Python 基本介绍及 print

Python 对於程序初学者来说是最简单好学的语言了,他的优点有 语法简化而不复杂 强调程序码的可...