国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【跟小嘉學(xué) Rust 編程】二十一、網(wǎng)絡(luò)編程

這篇具有很好參考價值的文章主要介紹了【跟小嘉學(xué) Rust 編程】二十一、網(wǎng)絡(luò)編程。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

系列文章目錄

【跟小嘉學(xué) Rust 編程】一、Rust 編程基礎(chǔ)
【跟小嘉學(xué) Rust 編程】二、Rust 包管理工具使用
【跟小嘉學(xué) Rust 編程】三、Rust 的基本程序概念
【跟小嘉學(xué) Rust 編程】四、理解 Rust 的所有權(quán)概念
【跟小嘉學(xué) Rust 編程】五、使用結(jié)構(gòu)體關(guān)聯(lián)結(jié)構(gòu)化數(shù)據(jù)
【跟小嘉學(xué) Rust 編程】六、枚舉和模式匹配
【跟小嘉學(xué) Rust 編程】七、使用包(Packages)、單元包(Crates)和模塊(Module)來管理項目
【跟小嘉學(xué) Rust 編程】八、常見的集合
【跟小嘉學(xué) Rust 編程】九、錯誤處理(Error Handling)
【跟小嘉學(xué) Rust 編程】十一、編寫自動化測試
【跟小嘉學(xué) Rust 編程】十二、構(gòu)建一個命令行程序
【跟小嘉學(xué) Rust 編程】十三、函數(shù)式語言特性:迭代器和閉包
【跟小嘉學(xué) Rust 編程】十四、關(guān)于 Cargo 和 Crates.io
【跟小嘉學(xué) Rust 編程】十五、智能指針(Smart Point)
【跟小嘉學(xué) Rust 編程】十六、無畏并發(fā)(Fearless Concurrency)
【跟小嘉學(xué) Rust 編程】十七、面向?qū)ο笳Z言特性
【跟小嘉學(xué) Rust 編程】十八、模式匹配(Patterns and Matching)
【跟小嘉學(xué) Rust 編程】十九、高級特性
【跟小嘉學(xué) Rust 編程】二十、進(jìn)階擴(kuò)展
【跟小嘉學(xué) Rust 編程】二十一、網(wǎng)絡(luò)編程

前言

本章節(jié)講解 Rust 標(biāo)準(zhǔn)庫(std::net 模塊)操作 TCP 和 UDP 編程

主要教材參考 《The Rust Programming Language》
主要教材參考 《Rust For Rustaceans》
主要教材參考 《The Rustonomicon》
主要教材參考 《Rust 高級編程》


一、 TCP

1.1、std::net::TcpListener

1.1.1、bind

TCP 服務(wù)端使用 std::net::TcpListener::bind 方法來監(jiān)聽IP地址和端口。該方法定義如下

 pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener>

我們可以看到泛型參數(shù) A 為 ToSocketAddrs 其實(shí)是一個 SocketAddr 的數(shù)組,我們可以使用 字符串方式來調(diào)用該方法 也可以使用數(shù)組的方式來使用。

use std::net::{SocketAddr, TcpListener};
fn main(){
    let listener  = TcpListener::bind("127.0.0.1:3000").unwrap();

    let addrs = [
	    SocketAddr::from(([127, 0, 0, 1], 80)),
	    SocketAddr::from(([127, 0, 0, 1], 443)),
    ];
	let listener = TcpListener::bind(&addrs[..]).unwrap();
}

兩種方式調(diào)用都可以,第二種就是綁定 80端口失敗,綁定端口443;

1.1.2、try_clone 方法

為 socket 創(chuàng)建一個新的句柄 ,兩個句柄都可以用于接受傳入的鏈接。

1.1.3、accept 方法

pub fn accept(&self) -> Result<(TcpStream, SocketAddr)>

從 監(jiān)聽器上接收一個新的連接,該方法返回 Result 。

use std::net::TcpListener;
#![allow(unused)]
fn main() {
	let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
	match listener.accept() {
	    Ok((_socket, addr)) => println!("new client: {addr:?}"),
	    Err(e) => eprintln!("couldn't get client: {e:?}"),
	}
}

1.1.4、incoming 方法

返回監(jiān)聽器上正在接收連接的迭代器,迭代器永遠(yuǎn)不會返回None,也不會產(chǎn)生一個 SokcetAddr 結(jié)構(gòu),相當(dāng)于循環(huán)調(diào)用 accept 。

use std::net::{TcpListener, TcpStream};

fn handle_connection(stream: TcpStream) {
   //...
}

fn main() -> std::io::Result<()> {
    let listener = TcpListener::bind("127.0.0.1:80")?;

    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                handle_connection(stream);
            }
            Err(e) => { /* connection failed */ }
        }
    }
    Ok(())
}

1.1.5、into_incoming 方法

這是一個 僅限 nightly 使用的實(shí)驗(yàn)性 API,參考 https://github.com/rust-lang/rust/pull/88339

#![feature(tcplistener_into_incoming)]
use std::net::{TcpListener, TcpStream};

fn listen_on(port: u16) -> impl Iterator<Item = TcpStream> {
    let listener = TcpListener::bind(("127.0.0.1", port)).unwrap();
    listener.into_incoming()
        .filter_map(Result::ok) /* Ignore failed connections */
}

fn main() -> std::io::Result<()> {
    for stream in listen_on(80) {
        /* handle the connection here */
    }
    Ok(())
}

1.1.6、ttl 相關(guān)方法

pub fn set_ttl(&self, ttl: u32) -> Result<()>
pub fn ttl(&self) -> Result<u32>

socket 發(fā)送 internet 協(xié)議數(shù)據(jù)包的生存時間值。

1.1.7、set_nonblocking

將 TCP 流設(shè)置成阻塞或非阻塞方式。

use std::io;
use std::net::TcpListener;

let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
listener.set_nonblocking(true).expect("Cannot set non-blocking");

for stream in listener.incoming() {
    match stream {
        Ok(s) => {
            // do something with the TcpStream
            handle_connection(s);
        }
        Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
            // wait until network socket is ready, typically implemented
            // via platform-specific APIs such as epoll or IOCP
            wait_for_fd();
            continue;
        }
        Err(e) => panic!("encountered IO error: {e}"),
    }
}

1.2、地址相關(guān)類

1.2.1、Ipv4Addr/IpV6Addr/IpAddr

IpAddr 枚舉

pub enum IpAddr {
    V4(Ipv4Addr),
    V6(Ipv6Addr),
}

使用方式

use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};

#![allow(unused)]
fn main() {


    let localhost_v4 = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
    let localhost_v6 = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
    
    assert_eq!("127.0.0.1".parse(), Ok(localhost_v4));
    assert_eq!("::1".parse(), Ok(localhost_v6));
    
    assert_eq!(localhost_v4.is_ipv6(), false);
    assert_eq!(localhost_v4.is_ipv4(), true);
}

1.2.2、SocketAddr/SocketAddrV4/SocketAddrV6

同樣 SocketAddr 是一個枚舉

pub enum SocketAddr {
    V4(SocketAddrV4),
    V6(SocketAddrV6),
}

使用用例:

use std::net::{Ipv4Addr, SocketAddrV4};
use std::net::{Ipv6Addr, SocketAddrV6};

fn main(){
    let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);

    assert_eq!("127.0.0.1:8080".parse(), Ok(socket));
    assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1));
    assert_eq!(socket.port(), 8080);

    let socket = SocketAddrV6::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 0, 0);

    assert_eq!("[2001:db8::1]:8080".parse(), Ok(socket));
    assert_eq!(socket.ip(), &Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1));
    assert_eq!(socket.port(), 8080);
}

1.3、std::net::TCPStream

使用 std::net::TCPStream 可以連接服務(wù)器、進(jìn)行數(shù)據(jù)讀取、寫入數(shù)據(jù);

1.3.1、connect 方法連接服務(wù)器

打開一個 Tcp 連接到遠(yuǎn)程主機(jī)。

pub fn connect<A: ToSocketAddrs>(addr: A) -> Result<TcpStream>

使用

use std::net::TcpStream;

if let Ok(stream) = TcpStream::connect("127.0.0.1:8080") {
    println!("Connected to the server!");
} else {
    println!("Couldn't connect to server...");
}

1.3.2、connect_timeout

pub fn connect_timeout(
    addr: &SocketAddr,
    timeout: Duration
) -> Result<TcpStream>

在超時時間內(nèi)打開一個遠(yuǎn)程主機(jī)的TCP連接。

1.3.3、shutdown

pub fn shutdown(&self, how: Shutdown) -> Result<()>

關(guān)閉連接讀、寫或都關(guān)閉。該函數(shù)將導(dǎo)致指定部分上的所有掛起和未來的I/O 立即返回一個適當(dāng)?shù)闹怠?/p>

特定平臺的行為

  • Linux 第二次調(diào)用將返回· OK(())·
  • macOS;將返回 ErrorKind::NotConnected, 將來可能會改變

1.3.4、try_clone

pub fn try_clone(&self) -> Result<TcpStream>

1.3.5、set_read_timeout 和 set_write_timeout

pub fn set_read_timeout(&self, dur: Option<Duration>) -> Result<()>
pub fn set_write_timeout(&self, dur: Option<Duration>) -> Result<()>

如果指定為 None 讀取調(diào)用將無限期阻塞,如果傳入 0 Duration 。則返回Err。

特定平臺行為:每當(dāng)設(shè)置此項導(dǎo)致讀取超時,平臺可能返回不同的錯誤代碼

  • Unix:返回一個類型為 WouldBlock 錯誤
  • Windows:可能返回 timeout;

1.3.6、peek

從連接上讀取數(shù)據(jù),不從隊列中刪除數(shù)據(jù),如果成功返回已peek的字節(jié)數(shù),連續(xù)調(diào)用返回相同的數(shù)據(jù)。

這是通過將MSG_PEEK作為一個標(biāo)志傳遞給底層的recv系統(tǒng)調(diào)用來實(shí)現(xiàn)的。

pub fn peek(&self, buf: &mut [u8]) -> Result<usize>

1.3.7、set_linger

這是一個 nightly 版本的 實(shí)驗(yàn)性 API。

pub fn set_linger(&self, linger: Option<Duration>) -> Result<()>

如果設(shè)置了 SO_LINGER,系統(tǒng)嘗試發(fā)送掛起數(shù)據(jù)時 ,sokect 將在指定時間內(nèi)保持打開狀態(tài),否則系統(tǒng)會立即關(guān)閉套接字 或等待默認(rèn)超時。

#![allow(unused)]
#![feature(tcp_linger)]
fn main() {
use std::net::TcpStream;
use std::time::Duration;

let stream = TcpStream::connect("127.0.0.1:8080")
                       .expect("Couldn't connect to the server...");
stream.set_linger(Some(Duration::from_secs(0))).expect("set_linger call failed");
}

1.3.8、set_nodelay

Rust 標(biāo)準(zhǔn)庫中的 TCP 流默認(rèn)啟用了 Nagle 的算法,它會避免高頻發(fā)送小量的數(shù)據(jù)包,所以數(shù)據(jù)不會總是立即發(fā)送,這會對一些場合的應(yīng)用產(chǎn)生影響(Rust TCP/Websocket 連接延遲波動)。

設(shè)置為 true 之后,會禁用 Nagle 算法。

pub fn set_nodelay(&self, nodelay: bool) -> Result<()>

示例

use std::net::TcpStream;

#![allow(unused)]
fn main() {
	let stream = TcpStream::connect("127.0.0.1:8080")
	                       .expect("Couldn't connect to the server...");
	stream.set_nodelay(true).expect("set_nodelay call failed");
}

二、 std::net::UdpSocket

可以用于 UDP 協(xié)議通信,通常用于低延遲比保證傳輸更重要的場景,例如:音頻/視頻流、網(wǎng)絡(luò)發(fā)現(xiàn)等。

2.1.1、bind 方法

pub fn bind<A: ToSocketAddrs>(addr: A) -> Result<UdpSocket>

從給定地址創(chuàng)建一個 UdpSocket 對象。使用方法和 TCPListener 差不多

2.1.2、recv_from 方法

pub fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>

接受單個數(shù)據(jù)包信息,如果成功,返回讀取的字節(jié)數(shù)和原始字節(jié)。函數(shù)必須使用有效字節(jié)數(shù)組調(diào)用,但必須有足夠大小來保存消息字節(jié),如果消息太長而無法轉(zhuǎn)入所提供的緩存區(qū)則會丟棄多余的字節(jié)。

use std::net::UdpSocket;
#![allow(unused)]
fn main() {
	let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
	let mut buf = [0; 10];
	let (number_of_bytes, src_addr) = socket.recv_from(&mut buf)
	                                        .expect("Didn't receive data");
	let filled_buf = &mut buf[..number_of_bytes];
	}

2.1.3、peek_from 方法

2.1.4、send_to 方法

發(fā)送數(shù)據(jù)到服務(wù)端

pub fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], addr: A) -> Result<usize>

返回成功寫入的字節(jié)數(shù)。

use std::net::UdpSocket;
#![allow(unused)]
fn main() {
	let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
	socket.send_to(&[0; 10], "127.0.0.1:4242").expect("couldn't send data");
}

2.1.5、try_clone 方法

2.1.6、set_read_timeout 和 set_write_timeout

2.1.7、UDP 廣播

2.1.7.2、廣播

廣播是一種一對多的通信,即目的是將數(shù)據(jù)報發(fā)送到網(wǎng)絡(luò)中的所有節(jié)點(diǎn)。對于點(diǎn)對點(diǎn)通信的情況不同,我們不必知道目標(biāo)主機(jī)的IP地址,而是使用廣播地址。

廣播地址是一個邏輯地址,連接到網(wǎng)絡(luò)的設(shè)備可以在該地址上接收數(shù)據(jù)包。

2.1.7.1、set_broadcast

pub fn set_broadcast(&self, broadcast: bool) -> Result<()>
pub fn broadcast(&self) -> Result<bool>

默認(rèn)值為false,設(shè)置為true之后,會開啟廣播

2.1.8、UDP 組播

2.1.8.1、組播

廣播效率低下,因?yàn)閿?shù)據(jù)包被發(fā)現(xiàn)倒網(wǎng)絡(luò)中的所有節(jié)點(diǎn),而不管他們是否有興趣接收通信,這可能是一種資源浪費(fèi)。多播解決了這個問題,并且只向感興趣的消費(fèi)者發(fā)送數(shù)據(jù)包

其中多播地址代表每個組。在IPv4 中,224.0.0.0 到 239.255.255.255 之間的任何地址都可以用作多播地址。只有訂閱組的那些節(jié)點(diǎn)才能接收傳送到該組的數(shù)據(jù)包。

2.1.8.2、set_multicast_loop_v4 和 set_multicast_loop_v6

獲取此套接字的 IP_MULTICAST_LOOP 選項的值。

2.1.8.3、set_multicast_ttl_v4 和 set_multicast_ttl_v6

設(shè)置組播 ttl 超時時間

2.1.8.4、leave_multicast_v4 和 leave_multicast_v6

接收端離開組播

2.1.8.5、join_multicast_v4 和 join_multicast_v6

接收端加入組播地址才能接收數(shù)據(jù)。

2.1.9、set_ttl

設(shè)置超時時間

2.1.10、set_nonblocking

pub fn set_nonblocking(&self, nonblocking: bool) -> Result<()>

總結(jié)

以上就是今天要講的內(nèi)容文章來源地址http://www.zghlxwxcb.cn/news/detail-691995.html

到了這里,關(guān)于【跟小嘉學(xué) Rust 編程】二十一、網(wǎng)絡(luò)編程的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【跟小嘉學(xué) Rust 編程】一、Rust 編程基礎(chǔ)

    【跟小嘉學(xué) Rust 編程】一、Rust 編程基礎(chǔ)

    【跟小嘉學(xué) Rust 編程】一、Rust 編程基礎(chǔ) 本系列旨在分享 Rust 學(xué)習(xí)心得,適合初學(xué)者入門,后續(xù)系列會有 Rust 項目實(shí)戰(zhàn)系列編程介紹。 主要教材參考 《The Rust Programming Language》 Rust 是一門新的編程語言,它可以讓每個人編寫可靠且高效的程序,使用于需要運(yùn)行時速度、需要內(nèi)

    2024年02月10日
    瀏覽(18)
  • 30天拿下Rust之網(wǎng)絡(luò)編程

    概述 ????????在現(xiàn)代軟件開發(fā)中,網(wǎng)絡(luò)編程無處不在。無論是構(gòu)建高性能的服務(wù)器、實(shí)時通信應(yīng)用,還是實(shí)現(xiàn)復(fù)雜的分布式系統(tǒng),對網(wǎng)絡(luò)編程技術(shù)的掌握都至關(guān)重要。Rust語言以其卓越的安全性、高性能和優(yōu)秀的并發(fā)模型,為網(wǎng)絡(luò)編程提供了堅實(shí)的基礎(chǔ)。 std::net ??????

    2024年04月14日
    瀏覽(25)
  • 【跟小嘉學(xué) Rust 編程】三、Rust 的基本程序概念

    【跟小嘉學(xué) Rust 編程】三、Rust 的基本程序概念

    【跟小嘉學(xué) Rust 編程】一、Rust 編程基礎(chǔ) 【跟小嘉學(xué) Rust 編程】二、Rust 包管理工具使用 【跟小嘉學(xué) Rust 編程】三、Rust 的基本程序概念 本章節(jié)涵蓋幾乎所有編程語言會出現(xiàn)的概念以及他們在 Rust之中的工作原理,這不是 Rust 獨(dú)有的,但我們將在 Rust 上下文中討論他們,并且

    2024年02月10日
    瀏覽(21)
  • 【跟小嘉學(xué) Rust 編程】三十、Rust 使用 Slint UI

    【跟小嘉學(xué) Rust 編程】三十、Rust 使用 Slint UI

    【跟小嘉學(xué) Rust 編程】一、Rust 編程基礎(chǔ) 【跟小嘉學(xué) Rust 編程】二、Rust 包管理工具使用 【跟小嘉學(xué) Rust 編程】三、Rust 的基本程序概念 【跟小嘉學(xué) Rust 編程】四、理解 Rust 的所有權(quán)概念 【跟小嘉學(xué) Rust 編程】五、使用結(jié)構(gòu)體關(guān)聯(lián)結(jié)構(gòu)化數(shù)據(jù) 【跟小嘉學(xué) Rust 編程】六、枚舉

    2024年02月04日
    瀏覽(26)
  • 【跟小嘉學(xué) Rust 編程】四、理解 Rust 的所有權(quán)概念

    【跟小嘉學(xué) Rust 編程】四、理解 Rust 的所有權(quán)概念

    【跟小嘉學(xué) Rust 編程】一、Rust 編程基礎(chǔ) 【跟小嘉學(xué) Rust 編程】二、Rust 包管理工具使用 【跟小嘉學(xué) Rust 編程】三、Rust 的基本程序概念 【跟小嘉學(xué) Rust 編程】四、理解 Rust 的所有權(quán)概念 本章節(jié)將講解 Rust 獨(dú)有的概念(所有權(quán))。所有權(quán)是 Rust 最獨(dú)特的特性,它使得 Rust 能夠

    2024年02月10日
    瀏覽(30)
  • 【跟小嘉學(xué) Rust 編程】十五、智能指針

    【跟小嘉學(xué) Rust 編程】一、Rust 編程基礎(chǔ) 【跟小嘉學(xué) Rust 編程】二、Rust 包管理工具使用 【跟小嘉學(xué) Rust 編程】三、Rust 的基本程序概念 【跟小嘉學(xué) Rust 編程】四、理解 Rust 的所有權(quán)概念 【跟小嘉學(xué) Rust 編程】五、使用結(jié)構(gòu)體關(guān)聯(lián)結(jié)構(gòu)化數(shù)據(jù) 【跟小嘉學(xué) Rust 編程】六、枚舉

    2024年02月11日
    瀏覽(22)
  • 【跟小嘉學(xué) Rust 編程】十九、高級特性

    【跟小嘉學(xué) Rust 編程】一、Rust 編程基礎(chǔ) 【跟小嘉學(xué) Rust 編程】二、Rust 包管理工具使用 【跟小嘉學(xué) Rust 編程】三、Rust 的基本程序概念 【跟小嘉學(xué) Rust 編程】四、理解 Rust 的所有權(quán)概念 【跟小嘉學(xué) Rust 編程】五、使用結(jié)構(gòu)體關(guān)聯(lián)結(jié)構(gòu)化數(shù)據(jù) 【跟小嘉學(xué) Rust 編程】六、枚舉

    2024年02月10日
    瀏覽(19)
  • 【跟小嘉學(xué) Rust 編程】十七、面向?qū)ο笳Z言特性

    【跟小嘉學(xué) Rust 編程】一、Rust 編程基礎(chǔ) 【跟小嘉學(xué) Rust 編程】二、Rust 包管理工具使用 【跟小嘉學(xué) Rust 編程】三、Rust 的基本程序概念 【跟小嘉學(xué) Rust 編程】四、理解 Rust 的所有權(quán)概念 【跟小嘉學(xué) Rust 編程】五、使用結(jié)構(gòu)體關(guān)聯(lián)結(jié)構(gòu)化數(shù)據(jù) 【跟小嘉學(xué) Rust 編程】六、枚舉

    2024年02月10日
    瀏覽(35)
  • 【跟小嘉學(xué) Rust 編程】六、枚舉和模式匹配

    【跟小嘉學(xué) Rust 編程】一、Rust 編程基礎(chǔ) 【跟小嘉學(xué) Rust 編程】二、Rust 包管理工具使用 【跟小嘉學(xué) Rust 編程】三、Rust 的基本程序概念 【跟小嘉學(xué) Rust 編程】四、理解 Rust 的所有權(quán)概念 【跟小嘉學(xué) Rust 編程】五、使用結(jié)構(gòu)體關(guān)聯(lián)結(jié)構(gòu)化數(shù)據(jù) 【跟小嘉學(xué) Rust 編程】六、枚舉

    2024年02月13日
    瀏覽(32)
  • 【跟小嘉學(xué) Rust 編程】十二、構(gòu)建一個命令行程序

    【跟小嘉學(xué) Rust 編程】一、Rust 編程基礎(chǔ) 【跟小嘉學(xué) Rust 編程】二、Rust 包管理工具使用 【跟小嘉學(xué) Rust 編程】三、Rust 的基本程序概念 【跟小嘉學(xué) Rust 編程】四、理解 Rust 的所有權(quán)概念 【跟小嘉學(xué) Rust 編程】五、使用結(jié)構(gòu)體關(guān)聯(lián)結(jié)構(gòu)化數(shù)據(jù) 【跟小嘉學(xué) Rust 編程】六、枚舉

    2024年02月13日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包