Quickstart
Setup
Install
rust can be installed like any other Dart package.
Dart:
dart pub add rust
Flutter:
flutter pub add rust
or add directly to your pubspec.yaml
:
dependencies:
rust: <version>
Imports
rust follows the same library structure and naming as Rust's core library.
To that extent, each library can be imported individually
import 'package:rust/result.dart';
or all libraries
import 'package:rust/rust.dart';
General Notes
All of rust's classes and methods are well documented in the docs, but being an implementation of Rust's core library, you can also refer to Rust core if anything is unclear. The functionally is the same.
The Basics
Result and Option
Result<T, E>
is a sum type used for returning and propagating errors - Ok
and Err
.
Option<T>
represents a value that can be either some value of type T
(Some<T>
) or None
.
It is used "in place" of T?
(implemented as a zero cost extension type of T?
).
These types can be easily chained with other operations or pattern matched.
The Rust ?
Operator and Early Return Key Notion
Result<T,E>
and Option<T>
both support early return key notation, which has
the same function as the rust ?
operator.
It returns from the scope if an Err
or None
is encountered, otherwise it retrieves the inner value.
Result example:
Result<double, String> divideBy(int num, int divisor) => divisor == 0 ? Err("Divide by zero error") : Ok(num / divisor);
Result<double, String> func(int x) => Result(($) { // Early Return Key
// The function will return here
int val = divideBy(x, 0)[$] + 10;
return Ok(val);
});
void main(){
assert(func(5) == Err("Divide by zero error"));
}
List
and Arr
Arr
(array) is a compliment to List
, representing a fixed sized List
. Having a separate Arr
type fixes runtime exceptions for trying to grow
a non-growable List
. It also has zero runtime cost, as it is an extension type of List
and is more efficient than a growable List
. With Arr
, type intent is clear for maintainers and developers are able think about code performance more critically.
var array = Arr(null, 10);
array = Arr.constant(const [1,2,3,4,5]);
array = Arr.generate(10, (i) => i);
for(final entry in array){
// do something
}
var (slice1, slice2) = array.splitSlice(3);
Iter
rust implements the entirety of Rust's stable and unstable Iterator methods. There are a lot of methods here that many Dart developers may not be familiar with. Definitely worth a look - docs
List<int> list = [1, 2, 3, 4, 5];
Iter<int> filtered = list.iter().filterMap((e) {
if (e % 2 == 0) {
return Some(e * 2);
}
return None;
});
expect(filtered, [4, 8]);
Iter
functions the same as a Rust Iterator
. For Dart developers, you can think of it as the union of Dart's Iterator
and Iterable
.
check here for more info.
Slice
A Slice
is a contiguous sequence of elements in a List
or Arr
. Slices are a view into a list without allocating and copying to a new list,
thus slices are more efficient than creating a new List
with .sublist()
e.g. list.sublist(x,y)
.
var list = [1, 2, 3, 4, 5];
var slice = Slice(list, 1, 4); // or `list.slice(1,4)`
expect(slice, [2, 3, 4]);
var taken = slice.takeLast();
expect(taken, 4);
expect(slice, [2, 3]);
slice[1] = 10;
expect(list, [1, 2, 10, 4, 5]);
Slice
also has a lot of efficient methods for in-place mutation within and between slices - docs
Whats Next?
Checkout any of the other sections in the book for more details and enjoy!