Part 2 of my adventures in Rust, part one
I upgraded to trunk (0.8) and let me say that in 0.8 the libraries make far more sense.
As we noted yesterday the keyword ‘pub’ allows you to note things as being public, aka able to export. So since our simplify module uses pub with Point and Simplify that means we can call
and it will bring those (and only) those into our scope. That being said a good programmer has a healthy level of paranoia that some else might screw up so it’s a good idea to only import the names you actually want into scope (This is non-rust specific advise so if rust is different please let me know) and we can do that here with
oh but wait that errors out if we do it, that’s because we have to declare what modules are in scope, which we can do in one of 2 ways, extern mod; links to a compiled library and mod without the extern links to an uncompiled one. Confusingly extern mod must be before any use ones, but mod (no extern) must be after, e.g.
so the first line links the compiled extra library, line 2 bring simplify and Point into scope allowing us to use them like we defined them in this file, the next line brings all things into the json library which is in the extra library into scope letting, and the next brings the library called path into scope, note that we don’t have to link to std but we do have to import stuff from it. Lastly we link to the uncompiled module called simplify.
The difference between what we did for json and path is that with json it’s Json type can be called as simply ‘Json’ but for path, it’s Path type has to be called as path::Path.
But then this causes an error
Remember how I said yesterday that if you leave the final semicolon of a function out of a function it just returns that value for the function? Well that applies to most everything so the reason that causes an error is that it is returning a value that can either be a string OR an int, and that’s a problem because this is valid.
Also since there isn’t any type coersion the statement actually has to be a bool, the only truthy value is true and the only falsey one is false (which is lowercase, the way it should be).
Now this isn’t full on Erlang style pattern matching, so no
But what you get instead is the ability to write branches to your program in a far more expressive and readable format, so instead of
you can use:
we’ve seen the underscore used before, and it is a placeholder for something we don’t care about. To soup it up even more, you can destructur inside the matches and use gaurds as shown in this example from the documentation
This is used by rust libraries to great effect as the main way to deal with operations that could error is to return something with the type ‘option’. This type is called that because, wait for it, it has the option of being different things. So if you want to turn a string x into a float y returning -1.0 if there is an error
You see this a lot where node would take a callback, Python would throw an error, and Erlang would be like fuck this I’m crashing.
Next up we have loops
The next loop type is the loop loop. Which is the equivalent of just doing while true and will go forever until you call break. I actually like this type of loop, I think this is because I often have very complex while loops where about half way through development and just replace the conditional with true and do this anyway.
For loops aren’t really documented in the main documentation but seem to be a crude form of python for loops. Basically containers have an iter method which is similar to the python next method the documentation is unclear if you have to always call the method directly, but calling it does work, as in simplify I iterate through the keys, ignoring the values of a smallIntMap called markers (which was supposed to be a smallIntSet, but the set is omitted from the actual source for some reason but still in the docs in 0.7)
dbaupp pointed out on reddit that the most correct (rustic one might say?) way to do this would be via a for loop over the range function ala
Iterators seem to have been put in in 0.8 and are used for the functional methods like map and zip, I will cover them once I figure out how the hell they work, probably after I figure out what all those ~ do.