New concepts #
Optionals #
An optional is either a value of type t
or a fault
, optional types are denoted by t?
, e.g. int?
. Optionals can be handled using
try
and catch
. The !
operator can be used to unwrap and re-throw a potential fault to the caller.
Defer #
defer
is used to ensure that something is performed at the end of a scope. For example closing a file.
Slices #
A slice denoted by type[]
is a struct containing a pointer and a size. An array can be sliced using the range syntax, for example
array[<start-index> : <slice-length>]
Example: Reading a file #
import std::io;
import std::io::file;
fn char[]? load_file(String filename)
{
File fh = file::open(filename, "rb")!;
defer (void)fh.close();
usz len = fh.seek(0, END)!;
fh.seek(0, SET)!;
char* buffer = malloc(len);
usz read = fh.read(buffer[:len])!;
return buffer[:len];
}
fn int main()
{
char[]? data = load_file("input.in");
if (catch err = data)
{
// handle err
io::eprintfn("Error: could not load file");
return 1;
}
io::printfn("%s", (String)data);
return 0;
}
Note: A similar implementation of load_file
is already provided by the standard library as file::load
.
Example: Writing to file #
import std::io;
import std::io::file;
String out_file = "output.out";
fn void? save_file(String filename, char[] data)
{
File fh = file::open(filename, "wb")!;
defer (void)fh.close();
fh.write(data)!;
}
fn int main()
{
char[] data = "Hello\nWorld\n";
if (catch err = save_file(out_file, data))
{
io::printfn("Error: unable to write to %s", out_file);
}
return 0;
}
Note: Again, a similar implementation of save_file
is already provided by the standard library as file::save
.