一種新的設計模式 newtype

2021-10-10 06:34:53 字數 2612 閱讀 8104

概述

設計模式是在編寫**時在各種不同情況下出現的模式。在本文中,我將討論 newtype 設計模式。具體來說,我將以 rust 程式語言為背景來討論它,以及如何解決在 rust 中使用 newtype 模式時出現的一些問題。

rust 的設計模式

程式設計設計模式是指在編寫**時在各種不同情況下出現的模式,這並不是說有了設計模式你就不需要自己去思考問題,而是設計模式給你提供了乙個工具箱,幫助你去思考解決方案。

不同的程式語言有不同的表達方式。關於設計模式的經典書籍《設計模式,elements of reusable object-oriented software》,圍繞物件導向的 c++ 和 smalltalk 為例介紹各種模式。雖然這些模式中的大部分仍然適用於其他物件導向的程式語言,但它們可能需要進行調整才能使它們很好地工作。

rust 是一門有趣的程式語言,因為該語言的設計借鑑了物件導向、過程式和函式式程式語言的思想。這意味著有不同的模式是有用的,現有的模式可能會以一種新的方式更好地表達。

問題描述:基本資料型別是非描述性的

想象一下,我們正在編寫乙個大型**庫。像許多專案一樣,專案包括一些使用者資訊,所以有乙個結構,如下。

pub struct person
幾個月後,在**庫的另乙個角落看到一些**,這可能從資料庫中刪除乙個人 ,函式引數如下:

pub fn load_person(person: string) -> result;
汗……那個引數是什麼字段?這個人的身份證 id 嗎?還是他的名字?

還有年齡字段可能也會讓人迷糊,比如說,你會如何實現這個函式?

pub fn time_to_retirement(current_age: u32) -> u32;
是以年為單位的年齡?一般情況下,時間戳都是以秒為單位儲存的,所以可能是傳遞乙個以秒為單位的年齡?

newtype 設計模式

newtype 模式是這樣場景,乙個結構體裡面有很多基本型別。

讓我們看看如何將它應用到 person 例子中。

你首先要定義 newtype。設計模式只是乙個值,包裹在乙個結構中。

pub struct name(string);

pub struct phonenumber(string);

pub struct idnumber(string);

pub struct years(u32);

如果你沒見過這樣的結構體,字段沒有命名,這個結構體叫 tuple struct。newtype 是它的乙個特例,只有乙個字段。

然後你可以開始在你的person結構中使用你的新型別。

pub struct person
好處顯而易見,我們的 load_person 函式更加清晰。比如型別是 idnumber 而不是 string,你就知道我們要傳入這個人的 id 號。

pub fn load_person(person: idnumber) -> result;
年齡字段現在也更清晰了,years 型別使得我們的年齡很明顯是以年為單位,而不是以秒為單位。

pub fn time_to_retirement(current_age: years) -> years;
字串是 newtypes 的常見用例,因為你可以用它們來增加對字串格式化的驗證。例如有些國家身份證號有特定的格式,因此可以更方便對其進行驗證。

構建示例

pub struct phonenumber(string);

impl phonenumber

pub fn as_str(&self) -> &str

}fn main() ", num.as_str())

}

構建及 parse 身份證號例子

// cargo-deps: derive_more = "0.99"

extern crate derive_more;

use derive_more::;

#[derive(display, debug, deref, partialeq)]

pub struct idnumber(string);

use std::str::fromstr;

impl fromstr for idnumber else

}}#[derive(display, debug, partialeq)]

pub enum idnumberparseerror

impl std::error::error for idnumberparseerror {}

fn main() ", id);

}

英文原文:

參考閱讀:

高可用架構

改變網際網路的構建方式

設計模式的一種 命令模式

命令模式是關於怎麼樣處理乙個物件請求另乙個物件呼叫其方法完成某項任務的一種模式,在命令模式中,當乙個物件請求另乙個物件呼叫其方法失,而又不想和被呼叫的物件發生直接關係,而是把請求組封裝在乙個請求物件中,既是把引用封裝在方法中,以達到傳送命令的效果 在呼叫時 被呼叫的只需要和命令物件打交道,四種角色 ...

一種新的 RESTful 許可權設計討論

根據restful的相關風格規範,我們將請求對映為以下幾種操作 get users list.users get users id retrieve.users post users create.users put users id password replace.users patch use...

一種新的乘法

做厭了乘法計算題的卡特,有一天突發奇想,創造了一種新的乘法運算法則。在這套法則裡,x y等於乙個取自x 乙個取自y的所有數字對的乘積的和。比方說,123 45等於1 4 1 5 2 4 2 5 3 4 3 5 54。對於2個給定的數x y 1 x,y 長整型最大數 你的任務是,用新的乘法法則計算x ...