Sugerencia: después de escribir el artículo, la tabla de contenido se puede generar automáticamente. Cómo generarla puede consultar el documento de ayuda a la derecha
Directorio de artículos
prefacio
Rust no es un lenguaje de programación orientado a objetos tradicional, y todas sus características lo hacen único. Por lo tanto, es necesario aprender patrones de diseño específicos de Rust. Esta serie de artículos son las notas de estudio del autor para aprender "Patrones de diseño de óxido" y sus propios conocimientos. Por lo tanto, la estructura de esta serie de artículos es también la misma que la de este libro (la estructura puede ajustarse más adelante), dividida básicamente en tres partes
- gramática idiomática
- Patrones de diseño
- Anti-patrones (anti_patrones)
Los modismos son estilos, pautas y patrones comunes para la programación en Rust que están ampliamente aceptados por la comunidad. Escribir código idiomático permite que otros desarrolladores entiendan mejor el código que escribes.
Este artículo es el inicio de esta serie de artículos, partiendo de las técnicas habituales de programación de Rust para empezar, correspondientes al libro de patrones de diseño, es decir, el tema de este número es
使用借用类型作为参数
。格式化字符串
构造函数
1. Usa tipos prestados como parámetros
El uso de un tipo prestado como parámetro puede evitar la capa de direccionamiento indirecto en el proceso de transferencia de parámetros de función. Por ejemplo, String tiene una capa de direccionamiento indirecto, &String tiene dos capas de direccionamiento indirecto. Podemos evitar esta situación usando &str, y dejar que se llame a &String cuando la función Cast to &str.
En este ejemplo, usamos &String como parámetro de función para comparar con &str.
Esto también se aplica a
&Vec<T>
with o&[T]
with .&Box<T>
&T
Tomando prestado un ejemplo del libro, por ejemplo, si queremos determinar si hay tres vocales en una palabra, usamos &String como parámetro para pasar, el código debe escribirse de la siguiente manera
Sonido original: aeiou
fn three_vowels(word: &String) -> bool {
let mut vowel_count = 0;
for c in word.chars() {
match c {
'a' | 'e' | 'i' | 'o' | 'u' => {
vowel_count += 1;
if vowel_count >= 3 {
return true
}
}
_ => vowel_count = 0
}
}
false
}
fn main() {
let ferris = "Ferris".to_string();
let curious = "Curious".to_string();
println!("{}: {}", ferris, three_vowels(&ferris));
println!("{}: {}", curious, three_vowels(&curious));
// 上面这么写是没有问题的,但是如果写成下面注释里面的样子,就会报错
// println!("Ferris: {}", three_vowels("Ferris"));
// println!("Curious: {}", three_vowels("Curious"));
}
Esta situación también es muy común en C++, porque el tipo de parámetro pasado en la firma de la función debe ser &String. Si "Ferris" se pasa directamente, es &str. Cuando se pasa a la función, no se verá forzado a convertir a &String, los amigos que aprenden C ++ deben estar muy familiarizados con este punto, si desea que sea posible pasar parámetros como ese, entonces la firma de la función debe cambiarse así
fn three_vowels(word: &str) -> bool {
De esta manera, no importa qué tipo de parámetro pasemos, se emitirá el resultado normal.
Ferris: false
Curious: true
Ahora probamos un ejemplo de este tipo, dada una oración, para determinar si cada palabra tiene tres vocales conectadas, para este propósito, cambiamos el código a lo siguiente
fn three_vowels(word: &str) -> bool {
let mut vowel_count = 0;
for c in word.chars() {
match c {
'a' | 'e' | 'i' | 'o' | 'u' => {
vowel_count += 1;
if vowel_count >= 3 {
return true
}
}
_ => vowel_count = 0
}
}
false
}
fn main() {
let sentence_string =
"Once upon a time, there was a friendly curious crab named Ferris".to_string();
for word in sentence_string.split(' ') {
if three_vowels(word) {
println!("{} 有三个连续的元音!", word);
}
}
}
Se puede ver que no hemos cambiado la función tres_vocales, pero en el lugar donde se llama a la función, use el método de división para dividir la cadena en varias palabras y pasarlas a la función a su vez. En este momento, los beneficios de &str se reflejan, y el valor devuelto por split Los elementos de la matriz son todos del tipo &str. Es muy simple convertir el tipo String a &str.
2. Cadena de empalme de formato
En términos generales, cuando estemos desarrollando, usaremos los métodos push y push_str del método String para el empalme de cadenas, o usaremos directamente + para lograr el empalme de cadenas, pero a veces puede ser más conveniente usar format!, especialmente una cadena de caracteres mixtos. tipos de cosas
Primero construimos manualmente una cadena
let mut hello = "Hello ".to_owned();
hello.push_str(name);
hello.push('!');
Este es un uso bastante común, ahora usamos formato para construir esta cadena
fn say_hello(name: &str) -> String {
format!("Hello {}!", name)
}
formato! devuelve una cadena formateada, {} se usa como marcador de posición, y luego los parámetros se pasan más tarde, y la cadena procesada se puede devolver. Es difícil ver sus beneficios en un lugar tan simple, pero cuando se inserta Cuando hay son muchas cosas, conocerás los beneficios de formatear cadenas.
Esta pieza tiene cosas similares tanto en python como en js. Creo que es fácil de usar en python y js. En js, solo
let hello = `hello ${name}`
En Rust, usar format! para formatear cadenas concatenadas es la forma más concisa y legible.
Tercero, usa el constructor
En Rust, en realidad no existe el concepto de un constructor, pero se puede usar una función asociada convencional new para crear un objeto. como
pub struct Second {
value: u64
}
impl Second {
// 构建一个Second实例
// 注意,这是个关联函数,参数里面没有self
pub fn new(value: u64) -> Self {
Self {
value }
}
/// 返回秒数,即Second的value
pub fn value(&self) -> u64 {
self.value
}
}
Creamos una segunda estructura e implementamos el nuevo método para construir un nuevo objeto.
Cuando está en uso, podemos crear un objeto llamando al nuevo método
let s = Second::new(42);
El rasgo predeterminado también se puede implementar en Rust para implementar el constructor predeterminado
impl Default for Second {
fn default() -> Self {
Self {
value: 0 }
}
}
Usar derivar para derivar Predeterminado también puede lograr el mismo efecto, por ejemplo, puede escribir
#[derive(Default)]
pub struct Second {
value: u64
}
impl Second {
pub fn value(&self) -> u64 {
self.value
}
}
En este punto no necesitamos el nuevo método, podemos llamar directamente al método predeterminado para construir la instancia
let s = Second::default();
注意:
Se recomienda usar new para crear el constructor. En desarrollo comunitario, new se suele usar para implementar el constructor, porque es más razonable que default y más acorde con los hábitos de lectura. Su función es la misma que default.
Resumir
Esta sección es el primer número del patrón de diseño de Rust e introduce principalmente alguna sintaxis idiomática del patrón de diseño de Rust.
- Usar tipos prestados como argumentos de función
- formato de cadena concatenada
- Constructor
Creo que a través de esta serie de artículos, puedes tener una comprensión más profunda de Rust.
Creé 一起学Rust
una comunidad e invito a los amigos que estén interesados en el óxido a unirse .
http://t.csdn.cn/AsEZ9