Rust 语言中的结构体

这篇具有很好参考价值的文章主要介绍了Rust 语言中的结构体。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1、结构体

2、结构体的定义和实例化

2.1 使用字段初始化简写语法

2.2 使用结构体更新语法从其他实例创建实例

2.3 没有命名字段的元组结构体

2.4 没有任何字段的类单元结构体

2.5 结构体示例程序

3、方法

3.1 关联函数

3.2 多个 impl 块


1、结构体

struct,或者 structure,是一个自定义数据类型,允许你包装和命名多个相关的值,从而形成一个有意义的组合。如果你熟悉一门面向对象语言,struct 就像对象中的属性。

2、结构体的定义和实例化

结构体和我们之前论过的元组类似,它们都包含多个相关的值。和元组一样,结构体的每一部分可以是不同类型。但不同于元组,结构体需要命名各部分数据以便能清楚的表明其值的意义。由于有了这些名字,结构体比元组更灵活:不需要依赖顺序来指定或访问实例中的值。

定义结构体,需要使用 struct 关键字并为整个结构体提供一个名字。结构体的名字需要描述它所组合的数据的意义。接着,在大括号中,定义每一部分数据的名字和类型,我们称为 字段field)。

我们看一下示例:

   struct people {
        name: String,
        age: u64,
    }

一旦定义了结构体后,为了使用它,通过为每个字段指定具体值来创建这个结构体的 实例。创建一个实例需要以结构体的名字开头,接着在大括号中使用 key: value 键 - 值对的形式提供字段,其中 key 是字段的名字,value 是需要存储在字段中的数据值。实例中字段的顺序不需要和它们在结构体中声明的顺序一致。换句话说,结构体的定义就像一个类型的通用模板,而实例则会在这个模板中放入特定数据来创建这个类型的值。

看一下示例:

   let user = People {
    name: String::from("zhou"),
    age: 23,
   };

为了从结构体中获取某个特定的值,可以使用点号。例如,我们获取一个用户对应的姓名和年龄,我们看下示例:

fn main() {
    struct People {
        name: String,
        age: u64,
    }
   let user = People {
    name: String::from("zhou"),
    age: 23,
   };
    println!("{} {} ", user.name, user.age)
} 

运行一下代码,看下是否可以获取对应的结果:

Rust 语言中的结构体,Rust,rust,开发语言,后端

我们也可以通过方法传参,来返回一个初始化的实例:

fn user(name: String, age:u64) -> People {
    People {
        name: name,
        age: age
    }
}

2.1 使用字段初始化简写语法

参数名与字段名都完全相同,我们可以使用 字段初始化简写语法,示例如下所示:

fn user(name: String, age:u64) -> People {
    People {
        name,
        age
    }
}

2.2 使用结构体更新语法从其他实例创建实例

使用旧实例的大部分值但改变其部分值来创建一个新的结构体实例通常是很有用的。这可以通过 结构体更新语法struct update syntax)实现。

我们可以看下如下示例:

fn main() {
    struct People {
        name: String,
        age: u64,
    }

fn user(name: String, age:u64) -> People {
    People {
        name,
        age
    }
}
let u = user(String::from("wangwu"), 12);
println!("{} {} ", u.name, u.age);   // wangwu 12 
let u1 = user(u.name, 34);           // wangwu 34 
println!("{} {} ", u1.name, u1.age);
}

可以使用u1中的一个值来创建一个新的People示例,如下所示:

fn main() {
    struct People {
        name: String,
        age: u64,
    }

let u1 = People {
        name: String::from("zhou"),
        age: 12,
    };

println!("{} {} ", u1.name, u1.age);   // zhou 12
let u2 = People {name: String::from("wangwu"),..u1};  // wangwu 12
println!("{} {} ", u2.name, u2.age);
}

使用结构体更新语法,我们可以通过更少的代码来达到相同的效果,.. 语法指定了剩余未显式设置值的字段应有与给定实例对应字段相同的值。

通过以上代码,我们可以知道u2创建了一个新的实例,实例中的name字段与u1实例中的name不一样,而其余的值则是与u1中字段一样,..u1必须放在最后,用来指定剩下的字段值都从u1中获取,而结构体字段的顺序是可以任意的。

2.3 没有命名字段的元组结构体

也可以定义与元组类似的结构体,称为 元组结构体tuple structs)。元组结构体有着结构体名称提供的含义,但没有具体的字段名,只有字段的类型。当你想给整个元组取一个名字,并使元组成为与其他元组不同的类型时,元组结构体是很有用的。

struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

fn main() {
    let black = Color(0, 0, 0);
    let origin = Point(0, 0, 0); 
}

注意 black 和 origin 值的类型不同,因为它们是不同的元组结构体的实例。你定义的每一个结构体有其自己的类型,即使结构体中的字段可能有着相同的类型。

2.4 没有任何字段的类单元结构体

我们也可以定义一个没有任何字段的结构体!它们被称为 类单元结构体unit-like structs)因为它们类似于 (),类单元结构体常常在你想要在某个类型上实现 trait 但不需要在类型中存储数据的时候发挥作用。

struct Color;
fn main() {
    let black = Color;
}

注意:之前定义结构体,我们使用了自身拥有所有权的 String 类型而不是 &str 字符串 slice 类型。这是一个有意而为之的选择,因为我们想要这个结构体拥有它所有的数据,为此只要整个结构体是有效的话其数据也是有效的。

可以使结构体存储被其他对象拥有的数据的引用,不过这么做的话需要用上 生命周期lifetimes

2.5 结构体示例程序

如果写一个计算长方形面积的方法,简单实现,可能会如下所示:

fn main() {
let w = 100;
let h = 200;
let result = area(w, h);
    println!("area is {:?}", result);
}

fn area (w: u64, h: u64) -> u64 {
    w * h
}

可以使用结构体,看起来更加语义化,如下所示:

struct AreaStruct {
    w: u64,
    h: u64
} 
fn main() {
    let a = AreaStruct {
        w: 100,
        h: 200
    };
let result = area(a);
    println!("area is {}", result);
}

fn area (a: AreaStruct) -> u64 {
    a.w * a.h
}

为了调试,我们可能会打印结构体里的属性,能,不过我们必须为结构体显式选择这个功能。为此,在结构体定义之前加上外部属性 #[derive(Debug)],如下所示:

#[derive(Debug)]
struct AreaStruct {
    w: u64,
    h: u64
} 
fn main() {
    let a = AreaStruct {
        w: 100,
        h: 200
    };
    println!("{:?}", a)
}

运行一下代码,看下打印结果,如下所示:

Rust 语言中的结构体,Rust,rust,开发语言,后端

另一种使用 Debug 格式打印数值的方法是使用 dbg!宏。dbg! 宏接收一个表达式的所有权(与 println! 宏相反,后者接收的是引用),打印出代码中调用 dbg! 宏时所在的文件和行号,以及该表达式的结果值,并返回该值的所有权。

示例如下所示:

#[derive(Debug)]

struct AreaStruct {
    w: u64,
    h: u64
} 
fn main() {
    let a = AreaStruct {
        w: 100,
        h: 200
    };
    dbg!(a);
}

运行代码,看一下打印结果:

Rust 语言中的结构体,Rust,rust,开发语言,后端

3、方法

方法(method)与函数类似:它们使用 fn 关键字和名称声明,可以拥有参数和返回值,同时包含在某处调用该方法时会执行的代码。不过方法与函数是不同的,因为它们在结构体的上下文中被定义,并且它们第一个参数总是 self,它代表调用该方法的结构体实例。

这是一个示例,如下所示:

#[derive(Debug)]
#[warn(dead_code)]

struct AreaStruct {
    w: u64,
    h: u64
} 
impl AreaStruct {
    fn area_me(&self) -> u64 {
        &self.w * &self.h
    }
    
}
fn main() {
    let a = AreaStruct {
        w: 100,
        h:100,
    };
    println!("value is {}", a.area_me())
}

在 C/C++ 语言中,有两个不同的运算符来调用方法:. 直接在对象上调用方法,而 -> 在一个对象的指针上调用方法,这时需要先解引用(dereference)指针。换句话说,如果 object 是一个指针,那么 object->something() 就像 (*object).something() 一样。

Rust 并没有一个与 -> 等效的运算符;相反,Rust 有一个叫 自动引用和解引用automatic referencing and dereferencing)的功能。方法调用是 Rust 中少数几个拥有这种行为的地方。

3.1 关联函数

所有在 impl 块中定义的函数被称为 关联函数associated functions),因为它们与 impl 后面命名的类型相关。我们可以定义不以 self 为第一参数的关联函数(因此不是方法),因为它们并不作用于一个结构体的实例。

不是方法的关联函数经常被用作返回一个结构体新实例的构造函数。这些函数的名称通常为 new ,但 new 并不是一个关键字。

示例如下所示:

struct AreaStruct {
    w: u64,
    h: u64
} 
impl AreaStruct {
    fn square(size: u64) -> Self {
        Self {
            w: size,
            h: size,
        }
    }
    
}

这样可以通过这个方法,返回一个新的实例。

3.2 多个 impl 块

结果体是允许有多个impl的实现的。我们可以写一个示例,如下所示:文章来源地址https://www.toymoban.com/news/detail-752466.html

#[derive(Debug)]
struct AreaStruct {
    w: u64,
    h: u64
} 
impl AreaStruct {
    fn area_me(&self) -> u64 {
        &self.w * &self.h
    }
}
impl AreaStruct {
    fn area_length(&self) -> u64 {
        &self.w * 2 +  &self.h * 2
    }
}
fn main() {
    let a = AreaStruct {
        w: 100,
        h:100,
    };
    println!("value is {}", a.area_length())
}

到了这里,关于Rust 语言中的结构体的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • rust学习-打印结构体中的vec

    将格式化后的数据写入到一个缓冲区(buffer),而不是直接打印到标准输出或文件中。 这个缓冲区可以是字符串,也可以是需要写入的文件的缓冲区。 writer 参数是一个实现了 std::io::Write trait 的对象,表示要将数据写入到哪里。 format_string 是一个格式化字符串,可以包含占位

    2024年02月12日
    浏览(39)
  • Rust 笔记:Rust 语言中哈希结构(哈希映射,HashMap)、集合(哈希集,HashSet)及其使用

    Rust 笔记 Rust 语言中映射(HashMap)与集合(HashSet)及其用法 作者 : 李俊才 (jcLee95):https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343 邮箱 : 291148484@163.com 本文地址 :https://blog.csdn.net/qq_28550263/article/details/130876735 【介绍】:本文介绍 Rust 中哈希结构相关概念及其使用。在 R

    2024年02月09日
    浏览(53)
  • Rust语言从入门到入坑——(2)Rust在windows上搭建开发环境

    开始搭建一个适合在windows上运行的Rust环境。 Rust支持的程序语言很多:可详见官网介绍 本文章主要是在windowns下搭建开发环境 首先,需要安装最新版的 Rust 编译工具和 Visual Studio Code。 Rust 编译工具:https://www.rust-lang.org/zh-CN/tools/install Visual Studio Code:https://code.visualstudio.com

    2024年02月09日
    浏览(52)
  • Rust软件外包开发语言的特点

    Rust 是一种系统级编程语言,强调性能、安全性和并发性的编程语言,适用于广泛的应用领域,特别是那些需要高度可靠性和高性能的场景。下面和大家分享 Rust 语言的一些主要特点以及适用的场合,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公

    2024年02月12日
    浏览(51)
  • Rust Web 全栈开发之 Web Service 中的错误处理

    数据库 数据库错误 串行化 serde 错误 I/O 操作 I/O 错误 Actix-Web 库 Actix 错误 用户非法输入 用户非法输入错误 编程语言常用的两种错误处理方式: 异常 返回值( Rust 使用这种) Rust 希望开发者显式的处理错误,因此,可能出错的函数返回Result 枚举类型,其定义如下: 例子 在

    2024年02月07日
    浏览(40)
  • 【Rust 基础篇】Rust 结构体详解

    在Rust中,结构体(Struct)是一种自定义数据类型,它允许我们将多个相关的值组合在一起,形成一个更复杂的数据结构。结构体在Rust中被广泛应用于组织和管理数据,具有灵活性和强大的表达能力。本篇博客将详细介绍Rust中结构体的概念、定义语法、方法以及相关特性,并

    2024年02月11日
    浏览(35)
  • 【Rust 基础篇】Rust 树形结构:实现与应用

    树形结构是计算机科学中一种常见的数据结构,它具有层级结构和递归特性。在 Rust 中,我们可以使用结构体和枚举等语言特性来定义树形结构,并通过引用和所有权等机制有效地管理数据。本篇博客将详细介绍 Rust 中树形结构的实现和应用,并包含代码示例和对定义的详细

    2024年02月16日
    浏览(39)
  • 【rust语言】rust多态实现方式

    学习rust当中遇到了这个问题,记录一下,不对地方望指正 多态是面向对象程序设计中的一个重要概念,指同一个行为或操作在不同实例上具有不同的行为或结果。简单来说,多态就是指同一种类型的对象,在不同的上下文中有不同的行为。多态性使得程序可以更加灵活、可

    2024年02月11日
    浏览(46)
  • C语言和Rust语言的互相调用(2)(Rust调用C)

    1.创建项目 rust调用c方式挺多的,这里采用最通俗易懂的方法,用构建脚本进行构建整个项目。 2.编辑build.rs的内容 这里的build.rs:若要创建构建脚本,我们只需在项目的根目录下添加一个 build.rs 文件即可。这样一来, Cargo 就会先编译和执行该构建脚本,然后再去构建整个项

    2024年02月02日
    浏览(51)
  • 【Rust 基础篇】Rust FFI:连接Rust与其他编程语言的桥梁

    Rust是一种以安全性和高效性著称的系统级编程语言,具有出色的性能和内存安全特性。然而,在现实世界中,我们很少有项目是完全用一种编程语言编写的。通常,我们需要在项目中使用多种编程语言,特别是在与现有代码库或底层系统交互时。为了实现跨语言的互操作性,

    2024年02月15日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包