A smaller batch of questions/ideas.
- This is an academic (useless) question because Rust is past V.1.0.
You can use a generics syntax like:
fn foo<T: Clone, K: Clone + Debug>(x: T, y: K) {...}
You can also use an alternative syntax like this, to declutter the signature when your types have complex trait constraints:
fn bar<T, K>(x: T, y: K)
where
T: Clone,
K: Clone + Debug {...}
But isn't "better" to always write the signatures like this, with the types always after the run-time arguments, and avoid the need of the "where" keyword?
fn foo(x: T, y: K)
<T: Clone,
K: Clone + Debug> {...}
-
This code shows the data sizes of some types:
fn main() {
use std::mem::size_of;
println!("{}", size_of::< Option >()); // 8
println!("{}", size_of::< Option<Option> >()); // 12
println!("{}", size_of::< Box >()); // 4
println!("{}", size_of::< Option<Box> >()); // 4
println!("{}", size_of::< Option<Option<Box>> >()); // 8
println!("{}", size_of::< Option >()); // 2
println!("{}", size_of::< Option<Option> >()); // 3
}
I don't know how much common such kinds of types are in Rust code, but I think the compiler can compress some representations. Some examples:
Option<Option<i32>> to just 8 bytes;
Option<Option<u16>> to just 4 bytes;
Option<Option<u8>> to just 2 bytes.
Another example:
enum Foo<T> { A(T), B(T), C(T) }
enum Bar<T> { D(T), E(T) }
enum Spam { F, G, H }
fn main() {
use std::mem::size_of;
type T1 = Foo<Bar<i32>>;
println!("{}", size_of::< T1 >()); // 12
type T2 = Foo<Bar<Spam>>;
println!("{}", size_of::< T2 >()); // 3
}
Perhaps the compiler can encode T1 in 8 bytes and T2 in 1 byte. This should reduce the memory used, but I don't know if this is going to speed up normal Rust programs.
- In the D standard library there's a second kind of Nullable:
It's similar to the Rust Option, but you can instantiate it specifying a value that represents the None state (the first Nullable version is more normal, it adds a second field, like Rust normally does). An usage example (this example usage assumes the array haystack to never have a length size_t.max
):
Nullable!(size_t, size_t.max) indexOf(string[] haystack, string needle) {...}
This has the advantage that:
Nullable!(size_t, size_t.max).sizeof == size_t.sizeof
Is something like this in the Rust std lib? I think you can implement a similar Option2 in Rust too (giving the None state as template argument is not strictly necessary, you can just use a different name for the structure).
(Perhaps Rust should offer safe and clean ways to optionally specify the bit-level representation of enum fields).
-
This little D program generates a lazy sequence (a Range), named "seq", and then prints it all:
void main() {
import std.stdio, std.range, std.algorithm;
auto seq = 100
.iota
.map!(x => x ^^ 2)
.filter!(x => x > 20)
.take(10);
seq.writeln;
}Output:
[25, 36, 49, 64, 81, 100, 121, 144, 169, 196]
I think the Rust println should handle and print lazy iterables too, this similar code doesn't compile:
fn main() {
let seq = (0 .. 100)
.map(|x| x * x)
.filter(|&x| x > 20i32)
.take(10);
println!("{:?}", seq);
}
If you want to tell apart the lazy sequences from the arrays in the println!("{:?}")
output you can even use semicolons instead of commas:
[25; 36; 49; 64; 81; 100; 121; 144; 169; 196]
- Do you know if there's an (updated) Rust cheatsheet? This page seems dead:
http://static.rust-lang.org/doc/master/complement-cheatsheet.html
Thank you for comments and answers.