
لفترة طويلة ، تم وضع Rust فقط كلغة برمجة نظام. غالبًا ما تسببت محاولات استخدام Rust للتطبيقات عالية المستوى في ابتسامة في جزء كبير من المجتمع: لماذا تستخدم الأداة بجودة لم يتم تصميمها من أجلها؟ ما هو استخدام الضجيج مع الأنواع واستعارة المدقق إذا كان لديك Python و Java مع جمع القمامة؟ لكن جزءًا آخر من المجتمع كان ينظر دائمًا إلى إمكانات Rust باعتبارها لغة تطبيق ، وحتى وجدها ملائمة للاستخدام في النماذج الأولية السريعة - ويرجع ذلك إلى حد كبير إلى ميزاته ، ولا يتعارض معها.
, Rust , . , , Rust . , , :
Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.
Rust — segfault' .
:
A language empowering everyone to build reliable and efficient software.
, .
, .
Rust, , , . , , Rust , .
?
/ , , . , — , Haskell — . Rust , Haskell, — . , , , : , , , .
, , . , , , . , - (DSL) , .
unsafe-
, Rust :
let a: Vec<_> = [1, 2, 3].iter().filter(|&i| i % 2 != 0).map(|i| i * 2).collect();
, — filter
map
, Vec
. — ( JavaScript). , Iter
, .iter()
:
pub struct Iter<'a, T: 'a> {
ptr: NonNull<T>,
end: *const T,
_marker: marker::PhantomData<&'a T>,
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
#[inline]
fn next(&mut self) -> Option<&'a T> {
unsafe {
assume(!self.ptr.as_ptr().is_null());
if mem::size_of::<T>() != 0 {
assume(!self.end.is_null());
}
if is_empty!(self) {
None
} else {
Some(next_unchecked!(self))
}
}
}
...
}
std::slice::Iter
, Iter
: ptr
end
( 2 3). - , — - ( NonNull
, ), , borrow checker'. 'a
(1) "" PhantomData<&'a T>
(4). , . , : , , , , . . , ( unsafe-, 5), API safe Rust.
, Rust . , , . , — , unsafe , ( : unsafe, , unsafe- ).
, , Rust — . . : "" Rust , API.
, unsafe, Rust — , . Rust : , , std
unsafe-? unsafe, safe. Rust , , . , Rust - .
, for
Python:
for x in range(5):
print(x)
Rust:
for x in 0..5 {
println!("{}", x);
}
, ? for
Rust — . for
:
match IntoIterator::into_iter(0..5) {
mut iter => loop {
let next;
match iter.next() {
Some(val) => next = val,
None => break,
};
let x = next;
let () = {
println!("{}", x);
};
},
}
for Loops and IntoIterator
, 0..5
for
, IntoIterator
, x
— , let
. , for
, :
macro_rules! foret {
($x:pat in $exp:expr => $body:expr) => {{
let mut result = None;
match IntoIterator::into_iter($exp) {
mut iter => loop {
let next;
match iter.next() {
Some(val) => next = val,
None => break result,
};
let $x = next;
result = Some($body);
},
}
}}
}
let result = foret!(x in 0..5 => {
println!("{}", x);
x
});
assert_eq!(result, Some(4));
Rust — — - . foret
. , : expr
( Rust ) , =>
. , , .
, , . , Rust — " ", Rust. Rust — , . , , . actix-web
:
use std::io;
use actix_web::{get, web, App, HttpServer, Responder};
#[get("/{id}/{name}/index.html")]
async fn index(info: web::Path<(u32, String)>) -> impl Responder {
format!("Hello {}! id:{}", info.1, info.0)
}
#[actix_rt::main]
async fn main() -> io::Result<()> {
HttpServer::new(|| App::new().service(index))
.bind("127.0.0.1:8080")?
.run()
.await
}
#[get(..)]
#[actix_rt::main]
— , , , . :
use std::io;
use actix_web::{get, web, App, HttpServer, Responder};
#[allow(non_camel_case_types, missing_docs)]
pub struct index;
impl actix_web::dev::HttpServiceFactory for index {
fn register(self, __config: &mut actix_web::dev::AppService) {
async fn index(info: web::Path<(u32, String)>) -> impl Responder {
{
let res = ::alloc::fmt::format(::core::fmt::Arguments::new_v1(
&["Hello ", "! id:"],
&match (&info.1, &info.0) {
(arg0, arg1) => [
::core::fmt::ArgumentV1::new(arg0, ::core::fmt::Display::fmt),
::core::fmt::ArgumentV1::new(arg1, ::core::fmt::Display::fmt),
],
},
));
res
}
}
let __resource = actix_web::Resource::new("/{id}/{name}/index.html")
.name("index")
.guard(actix_web::guard::Get())
.to(index);
actix_web::dev::HttpServiceFactory::register(__resource, __config)
}
}
fn main() -> io::Result<()> {
actix_rt::System::new("main").block_on(async move {
{
HttpServer::new(|| App::new().service(index))
.bind("127.0.0.1:8080")?
.run()
.await
}
})
}
index
HttpServiceFactory
, main
.
— html
yew
, Rust- html- DSL Web-:
impl Component for Model {
...
fn view(&self) -> Html {
html! {
<div>
<button onclick = self.link.callback(|_| Msg::Click)>{ "Click" }</button>
</div>
}
}
}
, , html- , Rust-. JSX, JavaScript. Rust , — .
. , , , Rust . , , . Rust - , .
( Python), "" , , Rust "", "" .
, , , . , , :
sleep(5);
, Rust:
use std::{thread, time::Duration};
thread::sleep(Duration::from_secs(5));
, - ? , .
, , Rust : , , , , . ( , Duration
, - , repr
.)
— "" , , . Rust :
struct Celsius(f64);
struct Fahrenheit(f64);
let a = Celsius(5.);
let b = Fahrenheit(5.);
, a
b
, . " " (New type), . ( " " .)
" ", Rust, . , , - . , , , .
, , . :
fn min<T: PartialOrd>(a: T, b: T) -> T {
if b < a { b } else { a }
}
, T
, . , , (traits), . . , , , . , . :
pub struct HashMap<K, V, S = RandomState> {
...
}
impl<K, V, S> HashMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher,
{
...
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
self.base.get(k)
}
...
}
std::collections::HashMap
get
-, V
, K
, Q
, ( K: Borrow<Q>
). ? , , , (K = String
) , get
(&Q = &K = &String
), , , (&Q = &str
), Borrow
. : , — get
.
- . . , :
pub struct UserId(u32);
, UserId
, , UserId
. ( , .)
UserId
-, , , UserId
- , . u32
! , , , , , , - , . , Borrow
:
impl Borrow<u32> for UserId {
fn borrow(&self) -> &u32 {
&self.0
}
}
get
. Q
— Q: ?Sized
. , Q
( ). , . , .
, , , , , . :
pub trait AsMapKey: ?Sized + Hash + Eq {}
impl<T: ?Sized + Hash + Eq> AsMapKey for T {}
, , . .
Rust - enum
, , , , . — (), .
— Value
serde_json
, JSON-:
pub enum Value {
Null,
Bool(bool),
Number(Number),
String(String),
Array(Vec<Value>),
Object(Map<String, Value>),
}
serde_json::Value
. , .
, enum
Rust , — ! — , . .
— . null
. , null
— , , . null
, null
, ( , ).
Rust:
pub enum Option<T> {
None,
Some(T),
}
std::option::Option
null
. , Option
, , . " ", , null
, Option
: Option::None
null
. Option
.
, " ".
Rust . . , , , , . , — . , Drop
.
Java, , try-with-resources
. , try-with-resources
. Cleaner
, — ( Java " finalize()? ").
Rust , , .
, -: , (), . , , :
mod machine {
pub struct StateA(String);
pub struct StateB(String);
pub struct StateC(String);
pub fn start(data: impl Into<String>) -> StateA {
StateA(data.into())
}
impl StateA {
pub fn step(self) -> StateB {
StateB(self.0)
}
}
impl StateB {
pub fn step(self) -> StateC {
StateC(self.0)
}
}
}
let a = machine::start("Hello");
let c = a.step().step();
machine
StateC
, StateA
, step
, StateB
. step
.
, . Rust .
, . , (view), . .
, String
, Deref
, : &String
&str
. , AsRef
, as_ref
&[u8]
, - &OsStr
&Path
. OsStr
String
, OsString
( ). Path
OsStr
:
pub struct Path {
inner: OsStr,
}
impl Path {
pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &Path {
unsafe { &*(s.as_ref() as *const OsStr as *const Path) }
}
...
}
std::path::Path source
, ? , Path::new
, &OsStr
, &OsStr
&Path
, , ( OsStr
Path
). , Path::new
, . String
Path
, String
OsStr
, , Path
.
-, Rust . , , . DTO-, diesel
. Rust — , , -, , .
?
, Rust — . , , : , .
? , . , . , , , Rust - .
, Rust- , . , Rust , , , , .