If
-
If .
if x >= 0 {
fmt.println("x is positive")
}
-
Initial statement :
-
Like
for, theifstatement can start with an initial statement to execute before the condition. -
Variables declared by the initial statement are only in the scope of that
ifstatement, including theelseblocks.
if x := foo(); x < 0 { fmt.println("x is negative") }if x := foo(); x < 0 { fmt.println("x is negative") } else if x == 0 { fmt.println("x is zero") } else { fmt.println("x is positive") } -
If Ternary
bar := 1 if condition else 42
// or
bar := condition ? 1 : 42
For
-
For .
-
It's the only type of loop.
-
Braces
{ }or adoare always required.
for i := 0; i < 10; i++ {
fmt.println(i);
}
for i := 0; i < 10; i += 1 { }
for i := 0; i < 10; i += 1 do single_statement()
for i in 0..<10 {
fmt.println(i)
}
// or
for i in 0..=9 {
fmt.println(i)
}
str: string = "Some text"
for character in str {
assert(type_of(character) == rune)
fmt.println(character)
}
-
Doesn't work :
-
My expectation here was that
a,bandcwould be elements from the return oftest(). It would be a way to iterate over multiples arrays at the same time.
test :: proc() -> ([5]f32, [5]int, [5]bool) { return {}, {}, {} } for a, b, c in test() { fmt.printfln("a: %v, b: %v, c: %v", a, b, c) } for a, b, c in [5]f32{}, [5]int{}, [5]bool{} { fmt.printfln("a: %v, b: %v, c: %v", a, b, c) } -
Custom Iterators
-
Loop arguments via the C loop pattern :
-
Only works for 1 loop argument, as far as I know.
memory_block_found := false for block := arena.curr_block; block != nil; block = block.prev { if block == temp.block { memory_block_found = true break } } -
-
Loop arguments via the
inpattern :-
The pattern is somewhat equivalent to
for a, b, ok := intersect_next(&iterator_idx, &A, &B); ok {; this version is specific doesn't work; theinpattern is a way to make it work. The last return value of the function must be a boolean, used to know whether to exit the loop or not. -
I believe this works for any number of loop arguments.
intersect_next :: proc(it: ^u32) -> (f32, [2]f32, bool, matrix[4,2]f32, bool) { if it^ == 4 { return 0, {}, false, {}, false } it^ += 1 @static v: f32 v += 1 return v, {}, false, {}, true } iterator_idx: u32 for float, vec, flag, mat in intersect_next(&iterator_idx) { fmt.printfln("float: %v vec: %v flag: %v matrix: %v", float, vec, flag, mat) }-
If removing the final
bool:-
The final type of 4-valued expression must be a boolean, got
matrix[4, 2]f32
-
-
-
Loop argument via indefinite loop and break :
-
Somewhat equivalent to the pattern above.
for { v := iter(&idx) or_break } idx: u32 for { float, vec, flag, mat := intersect_next(&idx) or_break fmt.printfln("float: %v vec: %v flag: %v matrix: %v", float, vec, flag, mat) } for idx: u32; true; { // `for idx: u32;; {` is not allowed float, vec, flag, mat := intersect_next(&idx) or_break fmt.printfln("float: %v vec: %v flag: %v matrix: %v", float, vec, flag, mat) } -
-
Loop arguments via out-parameters :
for intersect_next(&iterator_idx, &_velocities, &_positions, &vel, &pos) { } -
Doesn't work :
iterator_idx: u32 for a, b, ok := intersect_next(&iterator_idx, &A, &B); ok { }
Switch
-
switchis runtime. The compiler doesn't know if those cases are actually reachable or not, so it needs to check them all.-
The switch evaluates the possibility of entering each case, so the operation inside each case must be compatible.
-
-
The Switch has no fallthrough, but requires the use of the
casekeyword.
switch arch := ODIN_ARCH; arch {
case .i386, .wasm32, .arm32:
fmt.println("32 bit")
case .amd64, .wasm64p32, .arm64, .riscv64:
fmt.println("64 bit")
case .Unknown:
fmt.println("Unknown architecture")
}
Partial
Foo :: enum {
A,
B,
C,
D,
}
f := Foo.A
switch f {
case .A: fmt.println("A")
case .B: fmt.println("B")
case .C: fmt.println("C")
case .D: fmt.println("D")
case: fmt.println("?")
}
#partial switch f {
case .A: fmt.println("A")
case .D: fmt.println("D")
}
Type switch
-
vis the unwrapped value fromvalue.
value: Value = ...
switch v in value {
case string:
#assert(type_of(v) == string)
case bool:
#assert(type_of(v) == bool)
case i32, f32:
// This case allows for multiple types, therefore we cannot know which type to use
// `v` remains the original union value
#assert(type_of(v) == Value)
case:
// Default case
// In this case, it is `nil`
}
-
Note :
-
Having multiple types in a single case will mean it won't be unwrapped, as there's no one type the complier can guarantee it'll be.
-
Usage of
:
-
Barinzaya:
-
The case value can include
{
a := [2]int {1, 2} switch a { case {1, 2}: fmt.println(a) }-
You can add braces after the colon if you want, unadorned blocks are allowed anywhere a statement is.
-
Defer
-
Defer .
-
A defer statement defers the execution of a statement until the end of the scope it is in.
-
The following will print
4then234.
package main
import "core:fmt"
main :: proc() {
x := 123
defer fmt.println(x)
{
defer x = 4
x = 2
}
fmt.println(x)
x = 234
}