While TinyGo supports a big subset of the Go language, not everything is supported yet.
Here is a list of features that are supported:
deferkeyword is supported, with the exception of deferring a call on a function pointer. Immediately applied functions that are deferred are supported, however. In practice, function pointers are little used in deferred calls.
At the time of writing (2019-07-05), support for goroutines and channels has not been fully realized but simple programs usually work. There may be problems with function pointers or starting more than two goroutines. Also, some things may unexpectedly allocate heap memory like calling a function that blocks. This situation should certainly improve in the future: at the moment, you should treat goroutines as an experimental feature.
While TinyGo embeds the Clang compiler to parse
import "C" blocks, many features of Cgo are still unsupported. For example,
#cgo statements are currently ignored.
Many packages, especially in the standard library, rely on reflection to work. The
reflect package in the standards library is closely coupled to the main Go compilers and the runtime, so will have to be replaced. Work is underway that provides at least initial support for reflection.
Support for maps is not yet complete but is usable. You can use any type as a value, but only some types are acceptable as map keys. Also, they have not been optimized for performance and will cause linear lookup times in some cases.
Types supported as map keys include strings, integers, pointers, and structs/arrays that contain only these types. More complex types will depend on better reflection support.
Due to the above missing pieces and because parts of the standard library depend on the particular compiler/runtime in use, many packages do not yet compile.
While not directly a language feature (the Go spec doesn’t mention it), garbage collection is important for most Go programs to make sure their memory usage stays in reasonable bounds.
Garbage collection is currently only supported on ARM microcontrollers (Cortex-M). For this platform, a simple conservative mark-sweep collector has been implemented. Other platforms will just allocate memory without ever freeing it.
Careful design may avoid memory allocations in main loops. You may want to compile with
-gc=none and look at link errors to find out where allocations happen: the compiler inserts calls to
runtime.alloc to allocate memory. For more information, see heap allocation.
Some features are little used and there hasn’t been a real need to implement them yet. These include:
recover(): this can be useful sometimes but in general most programs work just fine with a
panic()that simply aborts. Supporting
recover()will also likely increase code size so it has also been left out at the moment for that reason. When
recover()gets implemented, it will likely be disabled by default and can be enabled with a compiler flag.