Live data from Hacker News

A half-hour to learn Rust

fasterthanli.me

21–30 of 150 posts

Re: A half-hour to learn Rust

#21
Every young language must have tutorials like this.

Start with the utter basics but move quickly through the common issues.

More than anything, these kinds of tutorials make it possible to at least start grasping the rest of the documentation.

I find with so many funky languages, the little examples aren't so hard, but there's too much 'unknown' syntax in the way to make sense of it.

These are essential.

Re: A half-hour to learn Rust

#22
post #19
post #12

> let x: i32 = 42; I'm sorry but this notation will always make me scream. C is so much simple: int x = 42; not "let", no colon, and no ambiguous "i32 = 42"

I just made a similar comment before I read yours, but about C# rather than C, where just like C you can do: `int x = 42;` But since int (32-bit integer) is the default integer type, you can also do: `var x = 42;` If you want to use another type, for example, ulong (unsigned, 64-bit integer), you can do: `ulong x = 42;` Or: `var x = 42ul;` C#'s syntax is not only terser, but seems a lot easier to read to me. With rus…

It's only clear because you already know what "long" and "int" mean in C#. It's potentially quite confusing for someone coming from a C or C++ background as they mean different things there. i32 and u32 on the other hand are ambiguously 32 bits.

In C++ I've actually had code using a value like `42l` that works on Linux but not on Windows, because the sizes of those types aren't fixed.

Re: A half-hour to learn Rust

#24
post #19

Earlier quoted context omitted.

I just made a similar comment before I read yours, but about C# rather than C, where just like C you can do: `int x = 42;` But since int (32-bit integer) is the default integer type, you can also do: `var x = 42;` If you want to use another type, for example, ulong (unsigned, 64-bit integer), you can do: `ulong x = 42;` Or: `var x = 42ul;` C#'s syntax is not only terser, but seems a lot easier to read to me. With rus…

It's only clear because you already know what "long" and "int" mean in C#. It's potentially quite confusing for someone coming from a C or C++ background as they mean different things there. i32 and u32 on the other hand are ambiguously 32 bits. In C++ I've actually had code using a value like `42l` that works on Linux but not on Windows, because the sizes of those types aren't fixed.

A valid point about knowing what the types mean, but even if you don't, it is at least immediately apparent which part is the type, and which part is the value.

I've only dabbled with rust, but I came across this very early on, and was baffled by the syntax. After further dabbling, I still can't see it and immediately know what the value is.

Re: A half-hour to learn Rust

#25
post #5

Numbers could also be differentiated in Rust. For example, to make sure your "16" is an i32 you could write > let x: i32 = 16i32; Otherwise, it's a very comprehensive article. The only missing parts are the async/await keywords and the sync primitives (like Mutexes/RwLocks).

You don't need both of those "i32"s. Rust has type inference, so you can just write either `let x = 16i32` or `let x: i32 = 16`.

Also you can use underscores in numeric literals. So you can write

  let x = 65536_i32;
Or

  let x: i32 = 65_536;

Re: A half-hour to learn Rust

#26
post #8

Earlier quoted context omitted.

You don't need both of those "i32"s. Rust has type inference, so you can just write either `let x = 16i32` or `let x: i32 = 16`.

I use it mostly if I'm passing arguments to another function. It serves as some sort of code documentation. > my_function( 44i32 ); That makes it clear from the code that function accepts an i32 and not any number.

The type signature of the function will also enforce that.

You can also use generics to allow you to accept a wider variety of numbers, e.g.:

  fn takes_a_float_like_number(number: T) where T: Into {
    // Number will now be a 64-bit IEEE floating point object
    // for this scope
    let number = number.into();
  }
This will only compile if your type is small enough to fit into an f64. So takes_a_float_like_number(500_u32) will compile but takes_a_float_like_number(500_i64) will not. The error message will be a wee bit obtuse as it will be something like "trait Into not implemented for i64".

Re: A half-hour to learn Rust

#27
post #17
post #5

Numbers could also be differentiated in Rust. For example, to make sure your "16" is an i32 you could write > let x: i32 = 16i32; Otherwise, it's a very comprehensive article. The only missing parts are the async/await keywords and the sync primitives (like Mutexes/RwLocks).

C# has a similar feature, but it's less verbose, e.g. "16l"/"16L" is a long (64-bit integer), "16u" is an unsigned, 32-bit integer etc. I find the rust syntax a little difficult to read. Take "16i32" for example - it's not immediately clear which part is the actual value.

The problem with "long" "unsigned" "short" "long long", etc. in the C world is that they all can mean different things depending on the architecture and compiler. i32, u64, f32, etc. make it very explicit what sized object you're working with. I'm not sure that's hugely applicable in C# land as there's only, what, two compilers and two? three? hardware architectures supported.

I agree that something like 16i32 is difficult to read which is why I typically use an underscore to separate the number from the type if I need to write a literal that way (e.g. sometimes I find 0_f64 easier to grok than 0.0).

Re: A half-hour to learn Rust

#28
post #12

> let x: i32 = 42; I'm sorry but this notation will always make me scream. C is so much simple: int x = 42; not "let", no colon, and no ambiguous "i32 = 42"

How do you feel about C's function pointer syntax?

To be pedantic, there is no (specialized) function pointer syntax. The syntax to declare function pointers is just general declaration syntax, which in turn is basically regular expression syntax.

How to declare a function pointer is hard to grok when not being introduced to declaring variables in a principled way. But it makes sense and is not too clunky if you're only declaring a function pointer every now and then.

Re: A half-hour to learn Rust

#29
post #11

Underscore is not exactly "throw away" but rather it is exactly "don't bind to variable". The difference becomes evident with the statement: let _ = x; This is a no-op and the value remains owned by the variable x, and is not thrown away.

I debated which terminology to use and thought "throwing away" was more intuitive, especially if you've never heard of "binding" before.

It has its limits though - in your example I'd say you're throwing away the result of evaluating "x", just as if you did:

    x;

Re: A half-hour to learn Rust

#30
post #17

Earlier quoted context omitted.

C# has a similar feature, but it's less verbose, e.g. "16l"/"16L" is a long (64-bit integer), "16u" is an unsigned, 32-bit integer etc. I find the rust syntax a little difficult to read. Take "16i32" for example - it's not immediately clear which part is the actual value.

The problem with "long" "unsigned" "short" "long long", etc. in the C world is that they all can mean different things depending on the architecture and compiler. i32, u64, f32, etc. make it very explicit what sized object you're working with. I'm not sure that's hugely applicable in C# land as there's only, what, two compilers and two? three? hardware architectures supported. I agree that something like 16i32 is dif…

Not a problem with C#, but I recognise it's an issue with C.

I didn't know you could use an underscore to separate the type - I think that definitely helps!

Post reply on HN