Submit Search
Upload
Rust for professionals.pdf
•
0 likes
•
91 views
S
ssuser16d801
Follow
Rust for professionals
Read less
Read more
Software
Report
Share
Report
Share
1 of 25
Download now
Download to read offline
Recommended
golang_getting_started.pptx
golang_getting_started.pptx
Guy Komari
Native interfaces for R
Native interfaces for R
Seth Falcon
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
Mario Fusco
Hadoop + Clojure
Hadoop + Clojure
elliando dias
Hw09 Hadoop + Clojure
Hw09 Hadoop + Clojure
Cloudera, Inc.
Functional programming ii
Functional programming ii
Prashant Kalkar
Patterns for JVM languages JokerConf
Patterns for JVM languages JokerConf
Jaroslaw Palka
JavaScript Growing Up
JavaScript Growing Up
David Padbury
Recommended
golang_getting_started.pptx
golang_getting_started.pptx
Guy Komari
Native interfaces for R
Native interfaces for R
Seth Falcon
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
Mario Fusco
Hadoop + Clojure
Hadoop + Clojure
elliando dias
Hw09 Hadoop + Clojure
Hw09 Hadoop + Clojure
Cloudera, Inc.
Functional programming ii
Functional programming ii
Prashant Kalkar
Patterns for JVM languages JokerConf
Patterns for JVM languages JokerConf
Jaroslaw Palka
JavaScript Growing Up
JavaScript Growing Up
David Padbury
Testing for share
Testing for share
Rajeev Mehta
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015
Michiel Borkent
Introduction to Scalding and Monoids
Introduction to Scalding and Monoids
Hugo Gävert
Making JavaScript Libraries More Approachable
Making JavaScript Libraries More Approachable
Pamela Fox
Pune Clojure Course Outline
Pune Clojure Course Outline
Baishampayan Ghose
Go 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX Go
Rodolfo Carvalho
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Rails
elliando dias
Full Stack Clojure
Full Stack Clojure
Michiel Borkent
Big Data Scala by the Bay: Interactive Spark in your Browser
Big Data Scala by the Bay: Interactive Spark in your Browser
gethue
JavaScript.pptx
JavaScript.pptx
Govardhan Bhavani
C programming language tutorial
C programming language tutorial
javaTpoint s
Xdp and ebpf_maps
Xdp and ebpf_maps
lcplcp1
C# programming
C# programming
umesh patil
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
Loïc Descotte
Let's Go-lang
Let's Go-lang
Luka Zakrajšek
Opa presentation at GamesJs
Opa presentation at GamesJs
Henri Binsztok
A Sceptical Guide to Functional Programming
A Sceptical Guide to Functional Programming
Garth Gilmour
Let'swift "Concurrency in swift"
Let'swift "Concurrency in swift"
Hyuk Hur
Introduction To Groovy 2005
Introduction To Groovy 2005
Tugdual Grall
Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)
Phil Calçado
刘煜辉:通缩已开始,经济已经落入衰退象限.pdf
刘煜辉:通缩已开始,经济已经落入衰退象限.pdf
ssuser16d801
出国篇-关于日本养老的问题(为什么很多人会把日本作为养老的归宿)!.pdf
出国篇-关于日本养老的问题(为什么很多人会把日本作为养老的归宿)!.pdf
ssuser16d801
More Related Content
Similar to Rust for professionals.pdf
Testing for share
Testing for share
Rajeev Mehta
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015
Michiel Borkent
Introduction to Scalding and Monoids
Introduction to Scalding and Monoids
Hugo Gävert
Making JavaScript Libraries More Approachable
Making JavaScript Libraries More Approachable
Pamela Fox
Pune Clojure Course Outline
Pune Clojure Course Outline
Baishampayan Ghose
Go 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX Go
Rodolfo Carvalho
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Rails
elliando dias
Full Stack Clojure
Full Stack Clojure
Michiel Borkent
Big Data Scala by the Bay: Interactive Spark in your Browser
Big Data Scala by the Bay: Interactive Spark in your Browser
gethue
JavaScript.pptx
JavaScript.pptx
Govardhan Bhavani
C programming language tutorial
C programming language tutorial
javaTpoint s
Xdp and ebpf_maps
Xdp and ebpf_maps
lcplcp1
C# programming
C# programming
umesh patil
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
Loïc Descotte
Let's Go-lang
Let's Go-lang
Luka Zakrajšek
Opa presentation at GamesJs
Opa presentation at GamesJs
Henri Binsztok
A Sceptical Guide to Functional Programming
A Sceptical Guide to Functional Programming
Garth Gilmour
Let'swift "Concurrency in swift"
Let'swift "Concurrency in swift"
Hyuk Hur
Introduction To Groovy 2005
Introduction To Groovy 2005
Tugdual Grall
Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)
Phil Calçado
Similar to Rust for professionals.pdf
(20)
Testing for share
Testing for share
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015
Introduction to Scalding and Monoids
Introduction to Scalding and Monoids
Making JavaScript Libraries More Approachable
Making JavaScript Libraries More Approachable
Pune Clojure Course Outline
Pune Clojure Course Outline
Go 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX Go
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Rails
Full Stack Clojure
Full Stack Clojure
Big Data Scala by the Bay: Interactive Spark in your Browser
Big Data Scala by the Bay: Interactive Spark in your Browser
JavaScript.pptx
JavaScript.pptx
C programming language tutorial
C programming language tutorial
Xdp and ebpf_maps
Xdp and ebpf_maps
C# programming
C# programming
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
Let's Go-lang
Let's Go-lang
Opa presentation at GamesJs
Opa presentation at GamesJs
A Sceptical Guide to Functional Programming
A Sceptical Guide to Functional Programming
Let'swift "Concurrency in swift"
Let'swift "Concurrency in swift"
Introduction To Groovy 2005
Introduction To Groovy 2005
Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)
More from ssuser16d801
刘煜辉:通缩已开始,经济已经落入衰退象限.pdf
刘煜辉:通缩已开始,经济已经落入衰退象限.pdf
ssuser16d801
出国篇-关于日本养老的问题(为什么很多人会把日本作为养老的归宿)!.pdf
出国篇-关于日本养老的问题(为什么很多人会把日本作为养老的归宿)!.pdf
ssuser16d801
欧美银行暴雷后,中国银行业并非理想避风港
欧美银行暴雷后,中国银行业并非理想避风港
ssuser16d801
检查你的事实并再试一次:利用外部知识和自动反馈改进大型语言模型 - 微软研究院.pdf
检查你的事实并再试一次:利用外部知识和自动反馈改进大型语言模型 - 微软研究院.pdf
ssuser16d801
留给普通人的最后一扇门,快要关闭了 __ Reader View.pdf
留给普通人的最后一扇门,快要关闭了 __ Reader View.pdf
ssuser16d801
uob-bank-fees-and-charges.pdf
uob-bank-fees-and-charges.pdf
ssuser16d801
rust-annual-report-2022-cn.pdf
rust-annual-report-2022-cn.pdf
ssuser16d801
More from ssuser16d801
(7)
刘煜辉:通缩已开始,经济已经落入衰退象限.pdf
刘煜辉:通缩已开始,经济已经落入衰退象限.pdf
出国篇-关于日本养老的问题(为什么很多人会把日本作为养老的归宿)!.pdf
出国篇-关于日本养老的问题(为什么很多人会把日本作为养老的归宿)!.pdf
欧美银行暴雷后,中国银行业并非理想避风港
欧美银行暴雷后,中国银行业并非理想避风港
检查你的事实并再试一次:利用外部知识和自动反馈改进大型语言模型 - 微软研究院.pdf
检查你的事实并再试一次:利用外部知识和自动反馈改进大型语言模型 - 微软研究院.pdf
留给普通人的最后一扇门,快要关闭了 __ Reader View.pdf
留给普通人的最后一扇门,快要关闭了 __ Reader View.pdf
uob-bank-fees-and-charges.pdf
uob-bank-fees-and-charges.pdf
rust-annual-report-2022-cn.pdf
rust-annual-report-2022-cn.pdf
Recently uploaded
EY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
Neo4j
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
stazi3110
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
Łukasz Chruściel
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
umasea
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
Diego Iván Oliveros Acosta
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
Technogeeks
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
Alina Yurenko
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
OPEN KNOWLEDGE GmbH
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
Velvetech LLC
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
bntitsolutionsrishis
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
Sujith Sukumaran
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
Christina Lin
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
smiwainfosol
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
jennyeacort
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
VICTOR MAESTRE RAMIREZ
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
VICTOR MAESTRE RAMIREZ
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Christina Lin
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Stefano Stabellini
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
qr0udbr0
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
Dinusha Kumarasiri
Recently uploaded
(20)
EY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
Rust for professionals.pdf
1.
overexact.com Rustforprofessionals Introduction Naming Syntax Variables Types Mutability Destructuring Functions Innerfunctions Extensionmethods Closures(lambdas) Expressions Structs(classes) Traits(interfaces) Defaultmethods Associatedfunctions Enums Associatedvalues Concepts Ownership Strings Nullvalues Errorhandling Input Attributes(annotations) Miscellaneous Packagemanagement Projectsetup Usefullinks Introduction ↑
2.
ThisisashortintroductiontoRust,intendedfordevelopersthatalreadyknowanother language.Intheexamples,RustiscomparedwithTypeScript,JavaScriptorJava,sometimes withC++orKotlin. ForadeepdiveintothesyntaxandRust’sconcepts,havealookatTheRustProgramming Language,butforaquickoverview,readon. Naming Regardingnames,Rustpreferssnakecaseforvariablesandfunctions,soamethodwould becalled read_str insteadof
readStr.Forstructs,traitsandenums,camelcase(orPascal case)isused,forexample HttpClient. Syntax Rust’ssyntaxisamixofexistinglanguages(curlybraces,functionsandreferenceslikeinC, typeafteridentifierlikeinGoorKotlin,genericsandtypeparameterslikeinC++orJava) withsomeRust-specificelements(lifetimenames,patterns,macros,attributes).Foraquick overviewofthesyntax,seetheRustLanguageCheatSheetoranoverviewofRust’s keywords. Variables RustvariabledeclarationsareverysimilartoTypeScriptorKotlin,butlookabitdifferentfrom JavaorC. const s: string = ""; let n: number = 0.9; let i = 123; // Type inferred let s: &str = ""; let mut n: f64 = 0.9; let mut i = 123; // Type inferred Mostofthetime,thetypecanbeommittedinRustandthecompilerwillinferthecorrecttype Types InRust,therearemorespecificprimitivedatatypes. Thevoidtypeiscalledunitandisindicatedby (),seefunctionsforanexample. int i = 123; long l = 456L; float f = 0.5f; double d = 0.5; TypeScript Rust Java ↑
3.
String string =
"Hello"; int[] arr = {1, 2, 3}; List<Integer> list = Arrays.asList(1, 2, 3); let i: i32 = 123; let l: i64 = 456; let f: f32 = 0.5; let d: f64 = 0.5f64; let string: &str = "Hello"; let arr: [i32; 3] = [1, 2, 3]; let list: Vec<i32> = vec![1, 2, 3]; InRust,numericliteralscanoptionallyhaveatypesuffix,forexample1000u32 or0.5f64. Mutability Variablesneedtobeexplicitlydeclaredmutable(let versus let mut),likeinJavaScript (const and let)orKotlin(val and var). ThemutabilitymodelinRustisnotlikeJavaScript,butabitmorelikeconstinC++,asRust willnotletyoucallmodifyingmethodsonavariablewhichisnotdeclaredasmutable. let arr1: string[] = []; arr1.push("123"); // OK arr1 = ["a", "b"]; // OK const arr2: string[] = []; arr2.push("123"); // OK, even though arr2 is const arr2 = []; // error, arr2 is const let mut arr1 = vec![]; arr1.push("123"); // OK arr1 = vec!["a", "b"]; // OK let arr2 = vec![]; arr2.push("123"); // error, arr2 is not mutable arr2 = vec![]; // error, arr2 is not mutable InTypeScript,declaringavariableasconst onlypreventsreassignment,notmodification.InRust,only variablesdeclaredasmut canbemodified Destructuring Rust TypeScript Rust ↑
4.
Rustsupportsdestructuring,likeJavaScriptorKotlin. function distance(a, b)
{ const { x: x1, y: y1 } = a; const { x: x2, y: y2 } = b; return Math.sqrt( Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2) ); } fn distance(a: &Point, b: &Point) -> f32 { let Point { x: x1, y: y1 } = a; let Point { x: x2, y: y2 } = b; ((x2 - x1).powf(2.0) + (y2 - y1).powf(2.0)).sqrt() } struct Point { x: f32, y: f32, } MoreexamplescanbefoundinthissectionfromtheRustforC++programmersguide Functions FunctionsarebasicallythesameasinC,Java,GoorTypeScript:Theyhaveaname,zeroor moreparametersandareturntype. void log(char* message) { printf("INFO %sn", message); } fn log(message: &str) -> () { println!("INFO {}", message); } Theunittype() (voidinsomelanguages)isthedefaultreturntypewhennotypeisgivenforafunction.It couldbeomittedinthisexample,likefn log(message: &str) { ... } InRust,functionsareexpressions,whichmeansthelaststatementisalsothereturnvalue (likeinRuby).Thisisabitlikeimplicitreturn,butnotexactly.Theofficialstyleistoonlyuse return forearlyreturns. public static int add(int a, int b) { return a + b; } JavaScript Rust C Rust Java ↑
5.
fn add(a: i32,
b: i32) -> i32 { a + b } NotethatthereisnosemicolonintheRustfunction,otherwiseitwouldreturnvoid Rustcurrentlyhasnonamedargumentsordefaultarguments(likePythonandTypeScript) anddoesnotallowmethodoverloading(likeC++,JavaorTypeScript). Innerfunctions Rustalsosupportsinnerfunctions. const RE = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/; function isValidRange(start, end) { function isValid(date) { return date && date.match(RE); } return isValid(start) && isValid(end); } use regex::Regex; const RE: &str = r"^[0-9]{4}-[0-9]{2}-[0-9]{2}$"; fn is_valid_range(start: &str, end: &str) -> bool { fn is_valid(date: &str) -> bool { !date.is_empty() && Regex::new(RE) .unwrap() .is_match(date) } is_valid(start) && is_valid(end) } NotethatRegex isanexternalcrateandnotpartofRust’sstandardlibrary Extensionmethods Rust(likeKotlin)alsosupportsextensionmethods,sothepreviousexamplecouldbe rewrittenusingextensions. typealias Range = Pair<String, String> fun Range.isValid(): Boolean { val (start, end) = this Rust JavaScript Rust Kotlin ↑
6.
return start.isNotEmpty() &&
end.isNotEmpty() } object Main { @JvmStatic fun main(args: Array<String>) { val range = Range("2020-01-01", "2020-12-31") if (range.isValid()) { println("Range is valid!") } } } type Range<'r> = (&'r str, &'r str); trait IsValid { fn is_valid(&self) -> bool; } impl<'r> IsValid for Range<'r> { fn is_valid(&self) -> bool { let (start, end) = &self; !start.is_empty() && !end.is_empty() } } fn main() { let range = ("2020-01-01", "2020-12-31"); if range.is_valid() { println!("Range is valid!"); } } InRust,extensionmethodsareaddedbyimplementingatrait.Whenthereisonlyonemethod,it’scommon tonamethetraitlikethemethod(IsValid).The'r denotesalifetime,formoreinformation,seethis sectionfromtheRustbook Closures(lambdas) Rustsupportsclosures(alsocalledLambdas,arrowfunctionsoranonymousfunctionsin otherlanguages). Whenaccessingvariablesfromoutsidetheclosure,RustismorestrictthanJavaScriptor Java,seecapturingformoredetails. function findEmails(list) { return list.filter( s => s && s.includes("@") Rust JavaScript ↑
7.
); } fn find_emails(list: Vec<String>)
-> Vec<String> { list.into_iter() .filter(|s| s.contains("@")) .collect() } Formorefilterexamples,seethissectionfromthedocumentation Expressions InRust,almosteverythingisanexpression,likeinKotlinanddifferentfromJavaScriptor Java.Youcandirectlyassigntheresultofan if statementtoavariable,forexample. function getLogLevel() { let level = process.env.TRACE ? "trace" : process.env.DEBUG ? "debug" : "info"; level = level === "trace" ? 0 : level === "debug" ? 1 : 2; console.log("using log level", level); return level; } fn get_log_level() -> u32 { let level = if std::env::var("TRACE").is_ok() { "trace" } else if std::env::var("DEBUG").is_ok() { "debug" } else { "info" }; let level = match level { "trace" => 0, "debug" => 1, _ => 2, Rust JavaScript Rust ↑
8.
}; println!("using log level
{}", level); level } TheRustcodeusesmatch,whichislikeswitch inJavaorJavaScriptexceptthatit’sanexpressionand providesmoreflexibility.Unlessmanyotherlanguages,Rustallowsvariableshadowingforlocalvariables (level inthisexample) Structs(classes) RustdoesnothavefullsupportforclasseslikeJavaorTypeScript,butinsteadoffersstructs (similartostructsinC).Thesearelikedatacontainerswithmethods,buttheydon’tsupport alloftheobjectorientedconcepts,likeinheritance. public class HttpClient { private final ClientImpl clientImpl; public HttpClient() { clientImpl = new ClientImpl(); } public String get(String url) { return clientImpl.newRequest() .get(url).asString(); } } public static void main(String[] args) { HttpClient httpClient = new HttpClient(); System.out.println(httpClient .get("https://example.com/")); } pub struct HttpClient { client_impl: ClientImpl, } impl HttpClient { pub fn new() -> HttpClient { HttpClient { client_impl: ClientImpl {}, } } pub fn get(&self, url: &str) -> String { self.client_impl.new_request() Java Rust ↑
9.
.get(url) .as_string() } } fn main() { let
http_client = HttpClient::new(); println!("{}", http_client.get("https://example.com/")); } InJava,mutabilityisgivenonafieldlevel,hereclientImpl isimmutable.InRust,themutabilitymodifieris setontheinstancevariableandnotperfield,soyoucannothavemutableandimmutablefieldsinthe samestruct(seetheInteriorMutabilityPattern) Methodsdonothaveimplicitaccesstothis,asinJavaorJavaScript,soyouneedtopassan explicitargumentnamed self,likeinPython.Methodswithoutthisparameterarecalled associatedfunctions(theyarecalledstaticmethodsinsomelanguages). InRust,thereisnoconstructor,structsarecreatedsimilarlytoobjectsinJavaScript.For caseswhereconstructorlogicisrequired,thereisaconventiontocreateanassociated function(staticmethod)named new,whichwillreturntheconstructedobjectinstance. Traits(interfaces) ThemostsimilarthingtointerfacesinRustaretraits. interface Named { fun name(): String } data class User( val id: Int, val name: String ) : Named { override fun name(): String { return this.name } } pub trait Named { fn name(&self) -> &String; } pub struct User { pub id: i32, pub name: String, } Kotlin Rust ↑
10.
impl Named for
User { fn name(&self) -> &String { return &self.name; } } Rustismostlyastaticlanguage,sosomethingsthatotherlanguagewilldoduringruntime, Rustwilldoduringcompiletime,whenpossible.Interfacesareusuallyusedfordynamic dispatchandifyouwanttousetraitsinasimilarway,seethischapteraboutstaticand dynamicdispatchandthisblogpost. Defaultmethods Traitsalsosupportdefaultmethods,likeinterfacesinJavaorKotlin. Associatedfunctions InRust,traitscanalsohaveassociatedfunctions,forexample from_str in std::str::FromStr (sectionstringparsingintheRustCookbook) interface FromList<T> { fun fromList(list: List<Int>): T? } data class MyPoint(val x: Int, val y: Int) { companion object : FromList<MyPoint> { override fun fromList(list: List<Int>): MyPoint? { return when (list.size) { 2 -> MyPoint(list[0], list[1]) else -> null } } } } object Main { @JvmStatic fun main(args: Array<String>) { val point = MyPoint.fromList(listOf(100, 200)) println(point) } } trait FromList<T> { fn from_list(list: &Vec<i32>) -> Option<T>; } struct MyPoint { Kotlin Rust ↑
11.
x: i32, y: i32, } impl
FromList<Self> for MyPoint { fn from_list(list: &Vec<i32>) -> Option<Self> { match list.len() { 2 => Some(MyPoint { x: list[0], y: list[1], }), _ => None, } } } fn main() { let point = MyPoint::from_list(&vec![100, 200]).unwrap(); println!("({}, {})", point.x, point.y); } FormoreinformationabouttheOption type,seetheNullvaluessectionbelow.ThekeywordSelf (upper case)canbeusedtoreferencethecurrenttype Enums Rustsupportsenums,likeJavaorKotlin,butwithmoreflexibility.TheRustenumsoffermore thaninC++orTypeScript,astheyarenotmerelyalistofconstants,butmorelikeunions. enum UserRole { RO("read-only"), USER("user"), ADMIN("administrator"); private final String name; UserRole(String name) { this.name = name; } String getName() { return name; } boolean isAccessAllowed(String httpMethod) { switch (httpMethod) { case "HEAD": case "GET": return true; Java ↑
12.
case "POST": case "PUT": return
this == USER || this == ADMIN; case "DELETE": return this == ADMIN; default: return false; } } } class Main { public static void main(String[] args) { UserRole role = UserRole.RO; if (role.isAccessAllowed("POST")) { System.out.println("OK: " + role.getName()); } else { System.out.println("Access denied: " + role.getName()); } } } #[derive(PartialEq)] enum UserRole { RO, USER, ADMIN, } impl UserRole { fn name(&self) -> &str { match *self { UserRole::RO => "read-only", UserRole::USER => "user", UserRole::ADMIN => "administrator", } } fn is_access_allowed( &self, http_method: &str, ) -> bool { match http_method { "HEAD" | "GET" => true, "POST" | "PUT" => { *self == UserRole::USER Rust ↑
13.
|| *self ==
UserRole::ADMIN } "DELETE" => *self == UserRole::ADMIN, _ => false, } } } fn main() { let role = UserRole::RO; if role.is_access_allowed("POST") { println!("OK: {}", role.name()); } else { println!("Access denied: {}", role.name()); } } Rustdoesnotsupportconstantsinenums,soweneedtouseamatchinthename method.Theenum matchesarecheckedatcompiletime,sowhenallenumvariantsareused,thereisnoneedtohavea defaultbranch. Formoreinformationaboutthe#[derive(PartialEq)] line,seethesectionaboutAttributes Associatedvalues Rustenumsalsosupportassociatedvalues,whichmeanstheyarenotconstant,butinstead allowthecreationofenumvariantinstanceswithspecificvalues. sealed class GitCommand { abstract fun execute() } object Status : GitCommand() { override fun execute() = executeCommand(listOf("status")) } class Checkout( private val branch: String ) : GitCommand() { override fun execute() = executeCommand(listOf("checkout", branch)) } class Add( private val files: List<String> ) : GitCommand() { override fun execute() = executeCommand(listOf("add") + files) } Kotlin ↑
14.
class Log( private val
decorate: Boolean, private val patch: Boolean ) : GitCommand() { override fun execute() { val args = mutableListOf("log") if (decorate) { args.add("--decorate") } if (patch) { args.add("--patch") } executeCommand(args) } } fun executeCommand(args: List<String>) { val redirect = ProcessBuilder.Redirect.INHERIT ProcessBuilder(listOf("git") + args) .redirectInput(redirect) .redirectOutput(redirect) .redirectError(redirect) .start() .waitFor() } object Main { @JvmStatic fun main(args: Array<String>) { val command = Log(decorate = false, patch = true) command.execute() } } use std::process::Command; pub enum GitCommand<'g> { STATUS, CHECKOUT(&'g str), ADD(Vec<&'g str>), LOG { decorate: bool, patch: bool }, } impl<'g> GitCommand<'g> { fn execute(self) { let args: Vec<&str> = match self { GitCommand::STATUS => vec!["status"], GitCommand::CHECKOUT(branch) => { vec!["checkout", branch] Rust ↑
15.
} GitCommand::ADD(files) => { [vec!["add"],
files].concat() }, GitCommand::LOG { decorate, patch, } => { let mut args = vec!["log"]; if decorate { args.push("--decorate") } if patch { args.push("--patch") } args } }; execute_command("git", &args); } } fn execute_command(command: &str, args: &[&str]) { Command::new(command) .args(args) .spawn() .expect("spawn failed!") .wait() .expect("command failed!"); } fn main() { let command = GitCommand::LOG { decorate: false, patch: true, }; command.execute(); } SealedClassesinKotlinaresimilartoRust’senums,astheyallowthemodellingofaclosedtypehierarchy Seethissectionaboutenumsformoreexamples. Concepts Ownership OnethingthatisveryspecialaboutRustisthewayithandlesmemoryallocations:Itdoesn’t haveagarbagecollector(likeJavaScript,JavaorGo),butthedeveloperdoesnotneedto ↑
16.
freememoryexplicitly,either(likeinC).Instead,Rustautomaticallyfreesmemorywhenitis nolongerinuse.Forthismechanismtowork,thedeveloperneedstoexplicitlythinkabout ownershipofthevaluestheprogramisusing. class User { private
String name; public User(String name) { this.name = name; } } public static void main(String[] args) { String name = "User"; User user1 = new User(name); User user2 = new User(name); } struct User { name: String, } fn main() { let name = String::from("User"); let user1 = User { name }; let user2 = User { name }; // compile error } InJava,thegarbagecollectorwillregularlychecktheobjectreferencesandwhennothingreferencesthe Userinstancesanymore,theywillbedeleted.Oncebothinstanceshavebeendetectedasunused,the "User" stringcanalsobedeleted. InRust,valuescanonlybeownedbyoneobjectatatime:theassignmenttouser1 isOK,becausethe valuewillbemovedfromthename variabletouser1.Thecreationofuser2,however,willgiveacompile error,becausethestring"User" isnowownedbyuser1,notbyname. InC,thedeveloperhastomakesurethatallocatedmemoryisfreedwhenitisnolonger needed.Thiscanleadtobugs(memoryleaks)andwasoneofthemotivationforRust’s differentapproachtomanagingmemory.WhileRustoffersprotectionsagainstit,it’snot impossibletohavememoryleaks. #include <string> std::string* get_string() { std::string* string = new std::string("hello"); delete string; Java Rust C++ ↑
17.
return string; } fn get_string()
-> String { let string = String::from("hello"); drop(string); return string; // compile error! } Inthisexample,theC++codehasauseafterfreeerror.Notethatthisisonlyanexample,dropisrarely usedinRustcode(valueswillbedroppedautomaticallywhentheygooutofscope) Rust’sownershipmodelalsohelpswhendealingwithmulti-threadedcode.Thecompiler keepstrackofthevaluestheprogramisusingandmakessurethatthesamevalueisnot accessedfrommultiplethreadswithoutproperlockinglogicaroundit. #include <vector> #include <thread> int main() { std::vector<std::string> list; auto f = [&list]() { for (int i = 0; i < 10000; i++) { list.push_back("item 123"); } }; std::thread t1(f); std::thread t2(f); t1.join(); t2.join(); } use std::thread; fn main() { let mut list = vec![]; let f = move || { for _ in 0..10000 { list.push("item 123"); } }; Rust C++ Rust ↑
18.
let t1 =
thread::spawn(f); let t2 = thread::spawn(f); // compile error! t1.join().unwrap(); t2.join().unwrap(); } Thestd::vector classisnotthread-safeandtheC++programwillcompilewithouterrors,butwhen running,itwillprobablycrashwithanerrorlikepointer being freed was not allocated orsimilar.In Rust,theclosuref takesownershipoflist (indicatedbythemovekeyword),that’swhythecompilergives anerrorwhenf isusedmorethanonce. Strings Rusthasmultiplestringtypes,themostimportantonesarestr(usuallyintheformof &str) andString. The &str typeonlyreferencesborrowedcontent,sothisisthetypethatisusedforstatic stringsandwhenreferencingstringslices.Likeotherimmutablereferences, &str values cannotbemodified.Use String ifyouneedamodifiablestring. const FILE_DATE = "2020-01-01"; function printCopyright() { const year = FILE_DATE.substr(0, 4); const copyright = `(C) ${year}`; console.log(copyright); } const FILE_DATE: &str = "2020-01-01"; fn print_copyright() { let year: &str = &FILE_DATE[..4]; let copyright: String = format!("(C) {}", year); println!("{}", copyright); } Seethissectionaboutstringsformoreexamples The String typeisusedfordynamicallycreatedstrings,whichcanbemodifiedandwhere thelengthisnotfixedatcompiletime. Usually, &str willbeusedforfunctionparametersand String willbeusedasreturnvalue. public static String repeat(String s, int count) { StringBuilder result = new StringBuilder(); for (int i = 0; i < count; i++) { result.append(s); } JavaScript Rust Java ↑
19.
return result.toString(); } fn repeat(s:
&str, count: u32) -> String { let mut result = String::new(); for _ in 0..count { result += s; } result } Thisisjustanexample,RustalreadyhasString.repeat Forstructfields,usually String shouldbeused,asthevaluewillprobablybeownedbythat struct,especiallywhendealingwithlongerlivingobjects. Forstringconstants, &'static str canbeusedforfieldsinstead. data class User( private val source: String, private val name: String, private val address: String ) { companion object { fun fromString(string: String): User { val lines = string.lines() return User("kotlin-v1.0", lines[0], lines[1]) } } } pub struct User { source: &'static str, name: String, address: String, } impl User { pub fn new(s: &str) -> User { let mut lines = s.lines(); User { source: "rust-v1.0", name: lines.next().unwrap().to_owned(), address: lines.next().unwrap().to_owned(), } } } Rust Kotlin Rust ↑
20.
Notethatdefaultfieldaccessisprivate inRust Toconvertavariable s1
oftype String to &str,use &s1. Toconvertavariable s2 oftype &str to String,use s2.to_owned() (thisallocatesnew memoryandcreatesacopyofthestring).Sometimesthisconversionisalsonecessaryfor literals,like "string literal".to_owned(). Nullvalues Rustdoesnothaveaspecial null value(alsocalled None or nil insomelanguages). Instead,thereistheOptionenum,whichisverysimilartotheOptionaltypeinJava. public static Integer getYear(String date) { if (date.length() >= 4) { String s = date.substring(0, 4); try { return Integer.valueOf(s); } catch (NumberFormatException e) { return null; } } else { return null; } } public static void main(String[] args) { Integer year = getYear("2020-01-01"); if (year != null) { System.out.println(year); } } fn get_year(date: &str) -> Option<u32> { if date.len() >= 4 { let s = date[..4]; match s.parse() { Ok(year) => Some(year), Err(_) => None } } else { None } } fn main() { if let Some(year) = get_year("2020-01-01") { println!("{}", year); Java Rust ↑
21.
} } TheOption typeisjustaregularenumfromRust’sstandardlibrary,withthetwoentriesNone andSome. WhenreturningOption,empty(null)valuescanbereturnedasNone
andnon-emptyvaluesneedtobe wrapped,likeSome(year) Tosimplycheckifavalueis null,withoutneedingtogettheactualvalue, is_none() can beused. Integer year = getYear(""); if (year == null) { System.err.println("Invalid date given!"); } let year: Option<u32> = get_year(""); if year.is_none() { println!("Invalid date given!"); } Sometimesit’susefultorunsomecodeonlyifavalueis null,toensureavariablehasa non-null value.TherearemanywaystodoitinRust,butusing match offersthemost concisesyntax. String url = "https://github.com"; String content = cache.get(url); if (content == null) { content = loadUrl(url); } let url = "https://github.com"; let content = match cache.get(url) { Some(content) => content, None => load_url(url), }; NotethatintheRustcode,content isimmutable(toachievethesameinJava,wewouldneedtointroduce anotherlocalvariableoranewmethod) Errorhandling RustdoesnotofferexceptionslikeC++,JavaorJavaScript.Instead,errorconditionsare indicatedviathemethod’sregularreturnvalue,likeinCorGo. Java Rust Java Rust ↑
22.
package main import ( "fmt" "log" "strconv" ) func
ParsePort(port string) (uint16, error) { p, err := strconv.ParseUint(port, 10, 16) if err != nil { return 0, err } if p == 0 { return 0, fmt.Errorf("invalid: %d", p) } return uint16(p), nil } func main() { port, err := ParsePort("123") if err != nil { log.Fatalf("failed to parse port: %v", err) } log.Printf("port: %d", port) } use std::error::Error; fn parse_port(s: &str) -> Result<u16, Box<Error>> { let port: u16 = s.parse()?; if port == 0 { Err(Box::from(format!("invalid: {}", port))) } else { Ok(port) } } fn main() { match parse_port("123") { Ok(port) => println!("port: {}", port), Err(err) => panic!("{}", err), } } InRustit’scommontohavestatementswhichcoverallpossiblecases,eitherusingif/else ormatch,so youarelesslikelytoencounteranearlyreturn inRustthaninGo Go Rust ↑
23.
Inthepreviousexample,weneededtouse Box<Error>,becausethereturnederrortype cannotbedeterminedduringcompiletime:Itwilleithercontainaninstanceof std::num::ParseIntError (fromtheparsemethod,whenparsingfails),orastring(when theportiszero). The
? intheline let port: u16 = s.parse()? isthe?operator:when parse returnedan error, parse_port willreturnthaterror,otherwisetheunwrappedresultof parse willbe assignedto port. Input Rustisoftenusedforterminalapplications,soitalsosupportsreadinginput.Therelevant codeisinthestd::iomodule. const { stdin } = require("process"); function readStr() { return new Promise((resolve, reject) => { let result = ""; stdin.setEncoding("utf8"); stdin.on("readable", () => { let chunk; while ((chunk = stdin.read())) { result += chunk; } }); stdin.once("error", err => reject(err)); stdin.once("end", () => resolve(result)); }); } use std::io::{stdin, Read}; fn read_str() -> Option<String> { let mut buffer = String::new(); match stdin().read_to_string(&mut buffer) { Ok(_) => Some(buffer), Err(err) => { eprintln!( "Error while reading input: {}", err ); None } JavaScript Rust ↑
24.
}; } NotethattheJavaScriptcodereturnsaPromise,soit’sasynchronous,whiletheRustexamplecodeis synchronous Attributes(annotations) Rustalsosupportsattributes(alsocalledannotationsinotherlanguages).Theyare interpretedduringcompiletimeandarecomparabletopreprocessormacrosinCorC++. #include <cstdint> [[nodiscard]] int32_t
add(int32_t a, int32_t b) { return a + b; } int main() { add(1, 2); // warning: unused return value } #[must_use] fn add(a: i32, b: i32) -> i32 { a + b } fn main() { add(1, 2); // warning: unused return value } Averycommonattributeisderive,whichcanbeusedtoquicklyimplementtraits.Itisoften usedlike #[derive(Debug, PartialEq)],toimplementtheDebugandPartialEqtraits. Miscellaneous Packagemanagement RustusuallyusestheCargopackagemanager,whichislikenpmoryarnforJavaScriptor MavenforJava. Thepackageregistryisavailableatcrates.io. Projectsetup IfyouhaveusedESLintbeforeforJavaScriptorTypeScript,rust-clippyisasimilartoolfor Rust,whichdetectscommonmistakesandbugs. C++ Rust ↑
25.
Theequivalentforprettierorgofmtisrustfmt,whichautomaticallyformatscodebasedon theofficialRuststyleguide. Usefullinks TheexcellentRustbook:https://doc.rust-lang.org/book/ RustbyExample:https://doc.rust-lang.org/rust-by-example/ TheRustCookbook:https://rust-lang-nursery.github.io/rust-cookbook RustLanguageCheatSheet:https://cheats.rs/ RustREPL:https://crates.io/crates/runner CommentsaboutRust:https://brson.github.io/fireflowers/ Thanksforreading!Ifyouhaveanyquestions,remarks,orjustwanttosaythanks,feelfree tocontactmeonTwitter Home Twitter GitHub
KeyBase ↑
Download now