Skip to content
Table of Contents

Introduction

Navi (/ˈnævi/) is a high-performance programming and stream computing language developed in Rust, originally designed for complex and high-performance computing tasks. It is also suited as a glue language embedded within heterogeneous services in financial systems.

In addition to its capabilities as a statically typed, compiled language, Navi offers the convenience of script-like execution. It can compile source code into Bytecode (without JIT) or Machine Code (with JIT), providing a flexible development workflow. Theoretically, Navi delivers competitive performance on par with Go, Rust, and C.

Language Design Philosophy

  • Simple and Clean Syntax

    Designed with a straightforward and clean syntax.

  • Modern Optional-Type and Error-Handling Design

    With a modern design of optional types and error handling, Navi allows developers to gracefully manage exceptional cases and abnormal data.

  • No NULL Pointer Panic, Safe Runtime

    No NULL pointer exceptions. Once your code passed compiles, you can expect consistent and reliable execution.

  • Scripted Execution

    Supports script-like execution, but offers the same performance comparable to compiled languages like Go.

Functionalities

  • Dual-Domain Programming

    Serves as a dual-purpose language, functioning as both a general-purpose programming language and a domain-specific language optimized for incremental computation.

  • High Performance

    As a statically typed, compiled language, which is comparable to Go, Rust, and C.

  • Cross-platform

    Running on Linux, Windows, macOS, and through WebAssembly (WASM), it extends its reach to iOS, Android, and Web Browsers.

  • Native Cloud Support (WIP)

    With its standard library, Navi enables seamless manipulation of cloud computing resources as if they were local.

  • Native Financial Support (WIP)

    Navi is equipped with native support for incremental financial data computation, making it ideal for real-time calculation and analysis of stock market data. It boasts a rich set of scientific computing capabilities, including built-in functions for technical stock market indicators, and standard library support for LongPort OpenAPI, significantly reducing development costs for programmatic trading.

Standard Library

The Navi Standard Library has its own documentation.

Getting Started

Write a main.nv, .nv is the file extension of the Navi language.

nv

Output:

shell

NOTE: If the file name is main.nv and it has the main function. The navi run will use it as the program entry. You also can execute with navi run main.nv.

This code sample demonstrates the basic syntax of Navi.

  • The use keyword is used to import the io module from the standard library.
  • The // is used to comment a line.
  • The fn keyword is used to define a function.
  • The main function is the entry point of the program, the main function must have the throws keyword, and it can throw an error.
  • The throws keyword is used to declare a function that can throw an error.
  • The let keyword is used to declare a variable.
  • The name variable is a string type, or you can use let name: string = "World"; to declare it.
  • The message variable is defined by a string interpolation (Like JavaScript) by using "``", and the ${name} is a variable reference.
  • The println function is used to print a string to the console, the println and print function is default imported from the std.io module.
  • Use ; to end a statement.
  • Finally, the Code style uses 4 spaces for indentation.\

Comments

Navi supports 2 types of comments (Like Rust).

The // started is a normal comment, and it will be ignored by the compiler.

For example:

nv,no_run

There is no multi-line comment in Navi. If you want to write a multi-line comment, just use // for each line.

Doc Comments

A doc comment is started with ///, and it will be parsed by the compiler and generate documentation. You can write Markdown in it.

For example:

nv,no_run

Doctest

You can write Markdown Code Block in your doc comment, and use navi test --doc to run the doc tests.

Like regular tests, doc tests use the assert, assert_eq, and assert_ne keywords for assertion.

For example:

nv,no_run

Then you can run navi test --doc to run the doc test.

shell

This will parse the code block in the doc comment and run it.

Annotation for doctest

Code blocks can be annotated with attributes that help navi test do the right thing when testing your code:

  • ignore: Ignore doc test (No compile and run).
  • should_panic: This code should panic or assert failed.
  • no_run: This code should pass compile but not run.
  • compile_fail: This code block should fail to compile.

For example:

Expect to ignore (No compile and run)

nv

Expect to panic or assert failed

nv

Expect to pass compile but not run

nv

Expect to compile failed

nv

Values

Primitive Types

TypeRust EquivalentDescriptionExample
inti64A signed integer type1, -29, 0
boolboolA boolean type.true, false
floatf64A floating point type1.0, -29.0, 0.0
stringstrA immutable UTF-8 string"Hello, 世界"
`Hello ${1 + 2}`
charcharA single character'a', 'b', 'c'

INFO

💡 Navi only has int and float types, all int are stored as int64, and all float are stored as float64 in internal.

There is no int8, uint8, int16, uint16, int32, uint32, float32, and etc.

Primitive Values

NameDescription
true and falsebool values
nilSet an optional value to nil

Integer

In Navi, the int type is a signed integer type, and it is 64-bit on all platforms. This means it can hold values from -9223372036854775808 to 9223372036854775807.

We don't have uint type or other integer types.

nv

You can use _ to separate digits in a number (int, float), it will be ignored by the compiler. This is useful for large numbers.

nv

Float

Navi has a float type (53 bits of precision), and it is 64-bit on all platforms.

nv

Bool

Navi has a bool type, and it has two values: true and false.

nv,

String

Use double quotes ("") or backticks (``) to create a string type.

In Navi all strings are IMMUTABLE, you can't change the value of a string.

nv,no_run

Output:

shell

Escape Sequences

Escape SequencesDescription
\nNewline
\rCarriage return
\tTab
\\Backslash
\"Double quote
\'Single quote

If you use \ in a string outside of an escape sequence, it will be ignored.

nv,no_run

Output:

shell

String Interpolation

String interpolation is a way to construct a new String value from a mix of constants, variables, literals, and expressions by including their values inside a string literal.

Navi's string interpolation is similar to JavaScript's template literals.

Use `` to create a string with interpolation, use ${} to insert a value or expression.

nv

ToString interface

The ToString interface is a built-in interface, and it has a to_string method, you can use it to convert a value to a string.

If you use any type that implements the ToString interface in string interpolation, it will call the to_string method to convert the value to a string.

For example:

nv

Char

Navi has a char type, and it represents a single Unicode scalar value.

nv

Byte and Bytes

Navi not have byte type, but you can use int to represent a byte value, we can use b'' to create a byte value from a char.

nv

Use b"" to create a Bytes type from a string.

nv

See also: std.io.Bytes

Assignment

Use the let keyword to declare a variable to an identifier, the variable is mutable.

nv,no_run

Output:

shell

You can declare a variable with a type.

nv

Type Casting

Use as to cast a value to a type, this is zero-cost type casting.

You can cast a value from int to float, or from float to int.

FROMTO
intfloat
floatint
boolint
nv

The following are invalid type casting:

nv,compile_fail

Type Conversion

Use parse_int, and parse_float to convert an string to a int or float, the return value is an optional type. If the string value is invalid, it will return nil.

Use to_string to convert all Primitive Types to a string, this is always successful.

nv

Testing

You can use the test keyword to declare a test function in any Navi file, it will be run when you execute navi test.

There are built-in assert, assert_eq, and assert_ne keyword for assertion.

nv

Output:

shell

Like navi run, you can use navi test main.nv to run a specific file, if you don't pass a file name, it will run all files in the current directory (Like navi test .).

The code in the test block will be ignored by the compiler when you execute navi run.

Test Declarations

You can use the test keyword to declare a test function, followed by a string literal as the test name, and then a block of code.

The test block can at anywhere in a Navi file, but it is recommended to put it at the end of the file.

nv

Output:

shell

Test Failures

The test runner will print the error message when a test fails, and with an exit 1 code to let CI know the test failed.

nv

Output:

shell

Track Caller

The #[track_caller] attribute can be used to mark a function as implicit caller location. When a function is marked with #[track_caller], the panic call stack will not include this function.

This is useful when you want to hide the internal implementation details of a function from the panic call stack.

For example we have a custom assert function:

nv

When the test faill, the panic call stack will not include the assert_success function:

shell

Caller Location

We can use call_location method in std.backtrace module to get the caller, it will return a CallerLocation type that contains the file and line number of the caller.

And the caller_locations function can returns [CallerLocation] that contains a ordered list by call stack.

nv

Output:

Variable

Declarations

The syntax of variable declarations is:

where:

  • declaration_mode - is the variable mode, we can use let, cost.
    • let - declare a mutable variable.
    • const - declare an immutable variable.
  • type - used to declare the variable type, such as int, string, or a optional type int?, string?.
  • identifier - variable name.
  • expression - the value of the variable, can be any expression.

Identifier

An identifier is a name used to identify a variable, function, struct, or any other user-defined item. An identifier starts with a letter or underscore _, followed by any number of letters, underscores, or digits.

It is recommended to use snake_case for identifiers, e.g. my_var, my_function_name.

They must not be a keyword. See Keywords for a list of reserved keywords.

The following are valid identifiers:

nv

And they are invalid identifiers:

nv,compile_fail

Variable Scope

Variables are scoped to the block in which they are declared. A block is a collection of statements enclosed by {}.

nv,no_run

Output:

shell

Const

The const keyword is used to declare an immutable variable, and it must have a value. When the value is assigned, it can't be changed.

nv

Operator

Like other programming languages, Navi has a set of operators for performing arithmetic and logical operations.

OperatorRelevant TypesDescriptionExample
+int, floatAddition1 + 2
+=int, floatAdditiona += 1
-int, floatSubtraction1 - 2
-=int, floatSubtractiona -= 1
*int, floatMultiplication1 * 2
*=int, floatMultiplicationa *= 1
/int, floatDivision.
Can cause Division by Zero for integers.
1 / 2
/=int, floatDivisiona /= 1
%int, floatModulo1 % 2
%=int, floatModuloa %= 1
-aint, floatNegation-1
a?.optionalOptionaluser?.name
a || 1optionalUnwrap optional value or use default value.
a || 0
a || bboolIf a is true, returns true without evaluating b. Otherwise, returns b.
a && 1bool
a!optionalUnwrap optional value or panica!
a == bint, float, bool, string ...a equal to b1 == 2
a == niloptionalAn optional value equal to nila == nil
a != bint, float, bool, string ...a not equal to b1 != 2
a != niloptionalAn optional value not equal to nila != nil
nv

Output:

shell

Array

Array is a collection of items, in Navi array is a mutable collection.

Use [] to declare an array, every array must have a type, you can't create an array without a type.

The left side array type is optional, if array init with items, the type will be inferred.

nv

If you init a empty array, you must declare the type.

nv

Get & Set Item

Use [idx], [idx]= to get and set an item from the array, the index must be an int type.

nv,should_panic

Mutate Array

There are push, pop, shift, unshift ... methods in Array, you can use them to mutate an array.

nv

Nested Array

The array can be nested.

nv

Map

Map is a collection of key-value pairs, in Navi map is a mutable collection.

Use {:} to declare a map, every map must have a type, you can't create a map without a type.

You use use any built-in type as a key, and any type as a value.

nv

If you init a empty map, you must declare the type, otherwise the type will be inferred.

nv

Get & Set Item

Use [key], [key]= to get and set an item from the map, the key must be a type that can be compared.

nv

Struct

The Navi struct is a collection of fields, and it is a value type, it's like a struct in Go and Rust.

Declare a Struct

Use the struct keyword to declare a struct, and use . to access a field.

  • The struct name must be an identifier with CamelCase style, e.g.: User, UserGroup, UserGroupItem.
  • And the field name must be an identifier, with snake_case style, e.g.: user_name, user_group, user_group_item.
  • The filed type can be a type or an optional type.
  • The field can have a default value, e.g.: confirmed: bool = false, and then you can create a struct instance without the confirmed field.
nv

To create a struct instance, use StructName { field: value } syntax.

If the variable name is the same as the field name, you can assign it in short syntax, e.g.: name is the same as name: name.

nv,

INFO

In the current version, you must assign nil to an optional field if you don't want to set a value.

We will support optional field default value to nil in the future.

nv,

Implement a Struct

Use impl to declare a struct method. The self is a keyword, it is a reference to the current struct instance. Unlike Rust, you don't need to declare self as the first parameter.

Use impl .. for to implement a interface for a struct. This is a optional way for let us write a clearly code, if the struct have a method can matched the interface, it same as the impl .. for implementation.

nv,
  • new is a Static Method, and it can be called by User.new.
  • say is an Instance Method, and it can be called by user.say().
nv,

Struct Attributes

Use #[serde(attr = ...)] to declare a struct serialize and deserialize attributes.

#[serde(rename_all = "...")]

Rename all the fields (if this is a struct) or variants (if this is an enum) according to the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE", "kebab-case", "SCREAMING-KEBAB-CASE".

nv,

Output:

json

#[serde(deny_unknown_fields)]

Always error during deserialization when encountering unknown fields. When this attribute is not present, by default unknown fields are ignored for self-describing formats like JSON.

NOTE

This attribute is not supported in combination with flatten, neither on the outer struct nor on the flattened field.

nv,

If we have a source JSON like this:

json

In this case, we still can deserialize the JSON to a struct, but the unknown_field will be ignored.

nv,

Field Attributes

#[serde(rename = "...")]

Serialize and deserialize this field with the given name instead of its Rust name. This is useful for serializing fields as camelCase or serializing fields with names that are reserved Rust keywords.

nv,

Output:

json

#[serde(alias = "name")]

Deserialize this field from the given name or from its Navi name. May be repeated to specify multiple possible names for the same field.

nv,

So both JSONs are valid:

json
json

#[serde(skip)]

Skip this field: do not serialize or deserialize it. The skip field must have a default value, otherwise, it will cause a compile error.

nv,

Output:

json

And also can deserialize the JSON without the group field.

nv,

#[serde(flatten)]

Flatten the contents of this field into the container it is defined in.

This removes one level of structure between the serialized representation and the Rust data structure representation. It can be used for factoring common keys into a shared structure, or for capturing remaining fields into a map with arbitrary string keys.

NOTE

This attribute is not supported in combination with structs that use deny_unknown_fields. Neither the outer nor inner flattened struct should use that attribute.

Flatten a struct fields

In some cases, we want to flatten a struct field to the parent struct. So we can use #[serde(flatten)] to do that.

nv,

Now all fields in the Profile struct will be flattened to the User struct after serialization.

json
Capture additional fields

A field of map type can be flattened to hold additional data that is not captured by any other fields of the struct.

nv,

For example, we have a lot of unknown fields in the JSON, the all unknown fields will be captured to the extra field.

json
nv,

Enum

The Navi enum is a collection of variants, and it is a value type.

Declare an Enum

Use enum keyword to declare an enum, and use . to access a variant. Enum only be an int type.

nv

The first variant will be 0, the second variant will be 1, and so on in order.

nv

Convert to a value

Use as to convert an enum to a value, this is zero-cost.

nv,

Enum Annotations

Like the struct, enum also has annotations for declaring serialize and deserialize attributes.

Enum Attributes

#[serde(int)]

Serialize and deserialize this enum as an integer.

nv,

If present, the serialized representation of the enum will be an integer.

json

Otherwise will use the enum field name as the serialized representation.

json
#[serde(rename_all = "...")]

This is the same as the struct #[serde(rename_all = "...")]. See Struct Attributes.

Please note that the rename_all attribute is not supported in combination with #[serde(int)].

Enum Item Attributes

The enum item also has annotations for declaring serialize and deserialize attributes.

#[serde(rename = "...")]

This is the same as the struct #[serde(rename = "...")]. See Struct Attributes.

#[serde(alias = "...")]

This is the same as the struct #[serde(alias = "...")]. See Struct Attributes.

Interface

The Navi interface is a collection of methods, and it is a value type, it's like an interface in Go.

Declare an Interface

Use the interface keyword to declare an interface, and use . to access a method.

  • The interface name must be an identifier with CamelCase style, we recommend named interface use a verb, e.g.: ToString, Read, Write.
  • And the method name must be an identifier, with snake_case style, e.g.: to_string, read, write.
  • We can write a default implementation for a method, and it will be used if the struct does not implement the method.
  • The first argument of the method must be self, it is a reference to the current struct instance.
nv,

Implement an Interface

If any struct has all methods of an interface, it will implement the interface.

nv,

Now we can use a User type as a ToString or a Read interface.

nv,

Type Assertion

Use .(type) to assert an interface to a type.

nv,

Switch

The switch statement is used to execute one of many blocks of code.

nv,no_run

Output:

shell

Use the switch keyword to declare a switch statement, the condition must have () and return a value. And use case and default to declare a case. The default case is optional, which means if the condition does not match any case, it will execute the default case.

You can also use {} to declare a block in case of more complex logic.

nv

Type switch

The switch can also used to assert the dynamic type of an interface variable. Use let t = val.(type) to assert the type of val in the switch condition.

The Any type is a special type that can hold any type of value.

nv

While

A while loop is used to repeatedly execute an expression until some condition is no longer true.

Use the while keyword to declare a while loop, the condition is an expression in () that returns a bool value.

nv,no_run

Output:

shell

Use the break keyword to exit a while loop.

nv,no_run

Output:

shell

Use continue to jump back to the beginning of the loop.

nv,no_run

Output:

shell

For

For loops are used to iterate over a range, an array, or a map.

Like while loop, you can use break and continue to control the loop.

Iter a Range

The range start..end contains all values with start <= x < end. It is empty if start >= end.

The for (let i in start..end) statement is used to iterate over a std.range.Range.

nv,no_run

Output:

shell

Use the step method to create a new range with a step.

nv

Iter an Array

The for (let item in array) statement is used to iterate over an [array].

nv,no_run

Output:

shell

Iter a Map

The for (let k, v in map) statement is used to iterate over a [map].

nv

Output:

shell

If

Like most programming languages, Navi has the if statement for conditional execution.

nv,no_run

If let

The if let statement is used to match an optional value.

nv,no_run

Output:

shell

Function

Use fn keyword to declare a function, the function name must be an identifier, and the function body must be a block.

INFO

Navi recommends using snake_case for the function name, e.g.: send_message, get_user, get_user_by_id.

And the argument name also uses snake_case, e.g.: title, user_id.

You can define a function at the module level, or in a struct impl block.

nv,no_run

Output:

shell

Positional Arguments

Positional arguments are arguments that are passed by position.

Use name: type to declare a positional argument, you can put a positional argument after the keyword argument.

nv

To define an optional type for an argument, we use ? after the type, e.g.: b: int?.

nv,no_run

Output:

shell

Arbitrary Arguments

Use ..type to declare an arbitrary argument, the arbitrary argument must be the last argument (Except Keyword Arguments).

This is means you can pass any number of arguments to the function. And this argument will be as an array in the function body.

nv

Keyword Arguments

Keyword arguments (Kw Args) are arguments that are passed by name. They are useful when a function has many arguments or default arguments.

Use name: value = default to declare a keyword argument, the keyword argument must be after positional arguments.

nv,no_run

Output:

shell

Function to a Variable

In Navi, the Function is the first-class citizen, it can be assigned to a variable, and it can be passed as an argument to another function.

nv,no_run

Closure

A closure is a function that captures the environment in which it was created. It can capture variables from the surrounding scope.

  • The closure type just use |(type, type): return_type|.
  • If there is no parameter, use |(): return_type|.
  • If no return type, use |(type, type)|.
  • If no parameter and return type, use |()|.
nv

Optional

Navi provides a modern optional type, which is similar to Rust's Option type, to give us a safe way to handle nil value, we can avoid the null pointer exception in runtime.

Use type? to declare an optional type, e.g.: string?, int?, float?, bool?, User? ...

nv

Now the optional_name is an optional type, it can be a string or nil.

Unwrap Optional

The ! operator is used to unwrap an optional value, if the value is nil, it will panic. It is useful when you want to get a value from an optional value and you are sure it is not nil.

NOTE

To keep your code safe, when you use !, you must be sure it is not nil.

If not, don't use it, the value || default is a better way to get a value from an optional value.

nv,no_run

Unwrap or Default

The || operator is used to unwrap an optional value, if the value is nil, it will return the default value.

The right side of || can be a value or an expression that returns a value, if the left side is not nill, the right side will not be evaluated.

nv

More methods

We also provide some methods to handle the optional value, such as map, and, and_then, is_nil, map_or, unwrap_or, expect, unwrap_or_else.

See also: Optional Methods.

nv,no_run

Error

The throws keyword on a function to describe that the function can be thrown an error.

NOTE

All functions whose signature is throws must use try, try? or try! keyword before it when you call it.

KeywordDescription
throwsThe function can throw an error.
tryThe error will be thrown, if the function throws an error.
try?If error is thrown, the try? will return nil.
try!If error is thrown, the try! will panic.
throwThrow an error.
doThe do block is used to handle an error.
catchThe catch block is used to match an error interface.
finallyThe finally block is optional, it will always be executed.
panicThe panic function is used to panic the program.

Error Interface

By default, throw can throw with a string or a custom error type that implements the Error interface.

TIP

Because Navi has implemented the Error interface for string, you can throw a string directly.

nv

So you can just throw string:

nv,

Or implement the Error interface for a custom error type:

nv

We can use throws to declare an error type or keep it empty to use default error.

nv,

For example:

nv,no_run

Catch Error

Use do ... catch statement to catch an error.

  • In the do block, you must use try keyword before all functions that can throw an error.
  • The catch block is used to match an error interface, it can have multiple catch blocks to match different error types.
  • And the finally block is optional, it will always be executed.

Every type that implements the error method can be used as an Error interface.

nv,ignore

Handle Error

try

If the function throws an error, the try will throw the error.

nv,

try?

If the function throws an error, the try? will return nil.

nv,

try!

If the function throws an error, the try! will panic.

nv,

Panic

The panic keyword is used to panic the program.

nv,

When panic is called, the program will stop running and print the error message.

Use

The use keyword is used to import a module from the standard library or a file.

nv

When you import, the last part of the module name is the name of the module, e.g.: use std.io to io, std.url.Url to Url, std.net.http to http.

Alias

Sometimes we may want to use a different name for a module, we can use as to import a module with an alias.

nv

Use multiple modules

We can use multiple modules by one use.

nv

Import a Module from local

In Navi, a folder in the current directory is a module, and the module name is the folder name.

For example, we have a struct:

shell

Now you can import them in main.nv:

nv,ignore

Module System

In Navi a folder in the current directory is a module, and the module name is the folder name.

  • The root directory is the main module, and uses main.nv as the entry file by default.
  • The any sub-directory as a sub-module, and use the directory name as the module name.
  • The root directory can have multiple entry files, and you can use navi run filename.nv to run it directly.
  • The pub keyword is used to export a struct, struct field, interface, function, type, enum, const, let, then the other modules can use it.

For example, we have a project like this:

shell

In this case:

  • main.nv, utils.nv files are in the main module, they can access and share members with each other.
  • models directory is a module named models.
  • models/user_profile.nv will be compiled into models module.
  • models/user_profile directory is a module named models.user_profile.
  • modles/user_profile/*.nv files will be compiled into models.user_profile module, they are same like one file.
  • config directory is a module named config.
  • config/*.nv files will be compiled to the config module, they are the same as one file.

NOTE

If your project has multiple sub-modules, you need to link them by use keyword to let the Navi compiler know the module dependency.

Only the used modules will be compiled, this means navi test or other commands will not find the sub-directory modules if you don't use them.

For example, in main.nv:

nv,

Type

We have type and type alias in Navi to create a type based on an existing type.

  • type is used to create a new type, user can not see the original type, and the new type not have any method of the original type. And we can use as the convert to the original type with zero cost.
  • type alias is used to create a new name for an existing type, the new name is acutally the same as the original type.

Use type keyword to create a newtype based on an existing type.

nv

Use type alias to create a new name for an existing type.

nv

Type Implementation

You can use impl to implement some method to a type alias.

NOTE

The type alias is not a new type, it is just an alias of the original type, so when you implement that type, the original type will also be changed.

nv

After this implementation, the User type will also have the new_method method.

Union Type

The union type allows us to combine two or more types into one type.

nv

It also can be used as a struct field type.

nv

Or with return type.

nv

Defer

The defer keyword is used to execute a block of code when the current function returns.

This is most like Go's defer keyword. It is useful when you want to do some cleanup work, e.g.: close a file, close a database connection, etc.

nv,

Output:

shell

Spawn

Navi has a spawn keyword for spawn a coroutine, it is similar to Go's go keyword.

nv

Unlike Go, Navi is a single-thread language, so the spawn is to make code run concurrently, not parallelly.

Difference in execution

Graph from Concurrency is NOT Parallelism

See also:

Channel

The channel is a communication mechanism that allows one goroutine to send values to another goroutine.

Use channel to create a channel, and use send to send a value to the channel, and use recv to receive a value from the channel.

nv,no_run

Keywords

The following are reserved keywords in Navi, they can't be used as identifier.

KeywordDescription
asConvert a value to a type.
assert_eqassert equal
assert_neassert not equal
assertassert
benchBenchmark function
benchesBenchmark group
breakbreak is used to exit a loop before iteration completes naturally.
casecase for the switch statement.
catchUse catch to catch an error.
constDeclare a constant.
continuecontinue can be used in a loop to jump back to the beginning of the loop.
defaultdefault case for switch statement.
deferExecute a block of code when the current function returns.
doUse do to handle an error.
elseelse can be used to provide an alternate branch for if, switch, while expressions.
enumDefine an enum.
falsefalse
finallyUse finally to execute a block of code after try and catch blocks.
fnDeclare a function.
forfor loop
ifif statement
implDeclare a struct implementation.
inkey use in for loop
interfaceDefine a [interface]
letDeclare a variable.
loopan infinite loop
nilAn optional value of nil.
panicPanic an error.
pubMark a function, struct, interface or enum as public.
returnReturn a value from a function.
selectUse to select a channel.
selfA reference to the current struct instance.
spawnSpawn a coroutine.
structDefine a struct.
switchswitch statement
testTest function
testsTest group
throwThrow an error.
throwsDeclare a function can throw an error.
truetrue
try
try?
try!
Use try to handle an error.
typeCreate a type alias.
useuse a module from the standard library or a file.
whilewhile loop