Saya menyajikan terjemahan sebuah artikel oleh Evan Cameron , yang dapat membantu pengembang Java lebih memahami perbedaan dan persamaan antara kedua bahasa - yang asli ada di situs penulis . Tidak menganggap diri saya seorang pengembang Rust yang berpengalaman, saya tidak mungkin dapat berpartisipasi secara wajar dalam diskusi yang memungkinkan.
Saya ingin membuat perubahan pada blog dan meninggalkan topik yang lebih sensitif untuk fokus pada mereka. Mungkin salah satu topik paling penting yang dapat dilakukan di komunitas Rust adalah pelatihan pengembang baru. Saya sedang memikirkan pendekatan terbaik untuk mengajar Rust bagi mereka yang terbiasa bekerja dengan Jawa dan membantu untuk menguasai bahasa untuk proyek baru.
Java adalah bahasa yang saya pelajari di universitas, jadi pengalaman saya dengannya agak ketinggalan zaman dan saya belum melakukan upaya nyata untuk mengikuti bahasa tersebut. Ketika saya terakhir menulis Java, jika Anda ingin melewatkan fungsi sebagai argumen, Anda harus mendeklarasikan antarmuka baru atau membungkus fungsi Callable<T>
. Sejak itu, Jawa telah berkembang pesat. Ini adalah fungsi yang ditambahkan yang memiliki efek yang jelas dari pemrograman fungsional. Saya berbicara tentang lambdas, Optional
tipe, dll. Artikel ini tidak akan berbicara tentang cara menulis di Rust atau Anda perlu membuang semua kode Java Anda. Java adalah bahasa yang bagus dengan kasus penggunaan nyata. Saya ingin membuat perbandingan Jawa dan Rust untuk programmer Rust pemula.
Motivasi bahasa
Pertama tentang tujuan setiap bahasa. Java diciptakan untuk memecahkan banyak masalah. Itu harus "sederhana, berorientasi objek dan modular" , itu harus bekerja dalam mesin virtual, menjadi portabel untuk berbagai arsitektur, dan harus memiliki kinerja tinggi. Tujuan Rust adalah untuk menjadi "sangat cepat dan efisien memori" , memiliki "sistem tipe kaya, keamanan memori, thread-safe", menghasilkan pesan kesalahan yang baik dan memiliki manajer paket bawaan.
. Rust , , . , Rust , . , , , , ( ) , (embedded) . , Rust. Rust , , (dangling) .
, Rust ( wasm frontends yew ). , , , , ( ) . .
, , Java Rust :
; , , . , .
Rust . Rust enum
struct
. enum
โ ( , ). enum
Java, , Java enum
, . enum
, , . , , Rust null
nil
. Rust, .
enum Option<T> {
None,
Some(T),
}
Option
, T
. T
, T
. Option
2 , None
(" ") , Some
T
. :
let a = Some("foo".to_string());
let b: Option<usize> = Some(1);
. , . , . , .
Rust enum
match
. , .
fn plus(a: Option<usize>) -> Option<usize> {
match a {
Some(v) => Some(v + 1),
None => None
}
}
, . match
. cheats.rs match
. if/else
.
Option
, - ( Some
) . , Option
, .
fn plus(a: Option<usize>) -> Option<usize> {
a.map(|v| v + 1)
}
|| {}
โ . Rust - , , " " .
struct
โ . , , , .
struct A {
field: usize
}
"" .
let a: (usize, usize) = (1, 1);
.
struct Foo<T> {
field: T
}
enum
struct
. , impl
. , Rust. struct
impl
, :
struct Thangs {
list: Vec<Thang>
}
struct Thang;
impl Thangs {
fn new() -> Self {
Self {
list: vec![]
}
}
fn add_thang(&mut self, thang: Thang) {
self.list.push(thang);
}
}
fn main() {
let mut thangs = Thangs::new();
thangs.add_thang(Thang);
}
Java, value.method()
" ". , &mut self
:
let mut thangs = Thangs::new();
Thangs::add_thang(&mut thangs, Thang);
, Rust . enum
struct
. Java - struct
impl
, "", ( , ). " Rust ", Java , . Java 14 "Records" () . , Java "", ( , Rust , sum product ). Java, - , , !
Rust . , . . :
struct Thing { field: usize }
fn main() {
let a = Thing { field: 1 };
}
- . , , Sized
. , . , ( main) .
Java, new
, , .
Box
( stdlib , Rc
, Arc
..). , , ? , , , , ( ). , , , , "" Box
, .
fn main () {
let a = Box::new(Thing { field: 1 });
}
, . , . , , a
a
. usize
, .
Box
. - Java,
trait Foo {}
struct Thing;
impl Foo for Thing {}
struct OtherThing;
impl Foo for OtherThing {}
fn main () {
let a: Vec<Box<dyn Foo>> = vec![Box::new(OtherThing), Box::new(Thing)];
}
trait
, . , . , . Rust , , , , .
, , . Rust โ .
.
enum List<T> {
Nil,
Cons((T, List<T>))
}
. List<T>
Nil
, Cons
, . , , ?
?
error[E0072]: recursive type `List` has infinite size
--> src/lib.rs:7:1
|
7 | enum List<T> {
| ^^^^^^^^^^^^ recursive type has infinite size
8 | Nil,
9 | Cons((T, List<T>))
| ------------ recursive without indirection
|
= help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `List` representable
. help
. , , . , , , N-? , , ? , . .
, .
enum List<T> {
Nil,
Cons((T, Box<List<T>>))
}
. , . .
Java Rust, ( ) :
enum Shape {
Circle { radius: f32 },
Rectangle { width: f32, height: f32 },
}
area
() , , , :
impl Shape {
pub fn area(self) -> f32 {
match self {
Shape::Circle { radius } => std::f32::consts::PI * radius.powi(2),
Shape::Rectangle { width, height } => width * height,
}
}
}
Java . Rust pub
( ), ( ). , Rust reference.
. Java Shape
Circle
Rectangle
, area
. Rust Java, :
Shape
:
- Java:
Shape
- Rust:
Shape
, ( match
, )
Shape
:
- Java: ""
Shape
, , - Rust:
impl
' ' (expression problem). . enum
Rust / Java. , Rust match
enum
. : ยซ , ?ยป
, .
trait Area {
fn area(self) -> f32;
}
struct Rectangle {
width: f32,
height: f32
}
struct Circle {
radius: f32
}
impl Area for Rectangle {
fn area(self) -> f32 {
self.width * self.height
}
}
impl Area for Circle {
fn area(self) -> f32 {
std::f32::consts::PI * self.radius.powi(2)
}
}
, Circle
Rectangle
, perimeter
, :
trait Perimeter {
fn perimeter(self) -> f32;
}
impl Perimeter for Rectangle {
fn perimeter(self) -> f32 {
2. * (self.width + self.height)
}
}
. , , "" " ".
fn do_something<T: Perimeter + Area>(shape: T) {
unimplemented!()
}
Rust . , , Java. , . Java , Rust . , . , , . Future
, Iterator
IntoIterator
for..in
, Index
[]
, Add
, Sub
, Mul
. , Add
Add
std.
pub trait Add<Rhs = Self> {
type Output;
fn add(self, rhs: Rhs) -> Self::Output;
}
Std Add
Rhs
, Self
, .. (1). ยซ ยป Output
(2) add
, self
( self
) rhs
Rhs
( ) , Output
(3).
use std::ops::Add;
#[derive(Debug)]
struct Content<T> {
val: T,
}
impl<T> Add for Content<T>
where
T: Add,
{
type Output = Content<<T as Add>::Output>;
fn add(self, rhs: Content<T>) -> Self::Output {
Content {
val: self.val + rhs.val,
}
}
}
fn main() {
let a = Content { val: 2 };
let b = Content { val: 5 };
println!("{:?}", a + b);
}
Content
, T
(1). Add
, Content
Add
(2), , Content
Add
(3). , Output
Content
Output
T
, Add
(4). , , , . , , . , " " , Rust. , Rust , ( ), .
, Sized
, fn foo<T>(t: T) -> T
, T: Sized
. T: ?Sized
, T
. .
Java . OO Rust, Java. Java โ (subtype polymorphism), Rust โ (ad-hoc) . , , , ( <T: Trait>
).
, "" . , enum
struct
, impl
. impl
, . , , -. .
Rust . str
, String
, OsStr
, OsString
, CString
CStr
( - ?). , str
String
, โ . , , ?
&str
, &str
&String
, String
Deref<Target=str>
( Target=
, Target
" "). .
fn foo<S: AsRef<str>>(s: S) {
unimplemented!()
}
AsRef
โ stdlib. :
trait AsRef<T>
where
T: ?Sized,
{
fn as_ref(&self) -> &T;
}
, T, , &T
. foo
String
,
let a = String::from("stuff");
foo(a);
? , ( ). Rust stdlib.
, . , , . , . Java ( , Java ). Java , . ยซ ยป. Rust , .
, , . , - . , , . Rust , ! , Rust .
.
: Java Rust
Java , . , . - Java , .. . , , Java , ( Java <T>
<T extends Class>
), Java , (type erasure). , Object
-. Java, , โ . - vtable, .
Rust . foo
foo
, foo
. , foo
4 AsRef<str>
, 4 . ยซยป. , Rust " ". ( Box
), Object
atau transfer tabel virtual jika kita tidak menginginkannya. Perlu dicatat bahwa kelemahan dari metode ini adalah ukuran kode akhir dan waktu kompilasi. Bergantung pada berapa banyak varian fungsi yang berbeda dan berapa banyak implementasi yang perlu kita hasilkan, semakin banyak kode yang harus melalui LLVM, meningkatkan waktu kompilasi dan meningkatkan jumlah kode yang sebenarnya dihasilkan.
Kontak Evan Cameron: surat , github , twitter , ditautkan dalam
Diskusi lambat tentang terjemahan Rust dilakukan dalam obrolan telegram untuk terjemahan Rust .