Created
September 25, 2017 00:41
-
-
Save vassvik/b868fe130858f5408387a54389b048c6 to your computer and use it in GitHub Desktop.
`using` in Odin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Odin has a powerful keyword called `using`, | |
// which is similar to the `using` keyword in other languages like C++, | |
// but also a lot more versatile and powerful in Odin. | |
// The simplest case, that is similar to C++'s usage: it makes the names of an import name visible | |
// in function scope. Be careful, as this might call name collision. | |
fmt.println("This is a new line"); | |
using fmt; | |
println("This is a new line, without fmt."); | |
fmt.println(); | |
// A related, but slightly different use for `using` is while importing a file: | |
// | |
// import "core:fmt.odin"; // created an import name `fmt` | |
// using import "core:fmt.odin"; // creates an import name `fmt`, while also make the imported names visible at file scope. | |
// | |
// You can also use it to make names inside structs visible at function scope: | |
Foo :: struct { | |
an_int: int = -1, | |
a_string: string = "uninitialized", | |
}; | |
using foo := Foo{42, "amazing"}; | |
fmt.println(foo.an_int, foo.a_string); | |
an_int = 13; | |
a_string = "fabulous"; | |
fmt.println(an_int, a_string); | |
fmt.println(); | |
// A particularly practical use-case for this is to loop over containers by reference: | |
foos: [10]Foo; | |
for _, i in foos { | |
using t := &foos[i]; | |
fmt.printf("i = %d: an_int = %v, a_string = '%v'\n", i, an_int, a_string); | |
an_int = i; | |
a_string = "initialized"; | |
} | |
for _, i in foos { | |
using foo := &foos[i]; | |
fmt.printf("i = %d: an_int = %v, a_string = '%v'\n", i, an_int, a_string); | |
} | |
// another useful case is to have implicit names in procedures, akin to methods in C++ where all the names in `this` is implicit | |
Weird_Struct :: struct { | |
a, b: int, | |
c, d: f64, | |
e: string, | |
}; | |
Silly_Struct :: struct { | |
f: int, | |
g: f64, | |
h: string, | |
}; | |
magic_proc :: proc(using w: ^Weird_Struct, using s: ^Silly_Struct) { | |
fmt.println(w^, s^); | |
w.b, s.f = s.f + 1, w.b - 2; | |
} | |
w: Weird_Struct; | |
s: Silly_Struct; | |
magic_proc(&w, &s); | |
magic_proc(&w, &s); | |
magic_proc(&w, &s); | |
magic_proc(&w, &s); | |
magic_proc(&w, &s); | |
magic_proc(&w, &s); | |
fmt.println(); | |
// It can be used in defining variables in structs: | |
Vec2 :: struct { | |
using xy: struct { | |
x: f32 = 1.0, | |
y: f32 = 2.0, | |
} | |
}; | |
v1: Vec2; | |
fmt.printf("xy = %v, x = %v, y = %v\n", v1.xy, v1.x, v1.y); | |
fmt.println(); | |
// An even crazier example: | |
Vec4 :: struct #raw_union { | |
xyzw: struct { | |
x, y, z, w: f32 | |
}, | |
using x_yzw: struct #ordered { | |
x: f32, | |
yzw: struct { | |
y, z, w: f32 | |
} | |
}, | |
using xyz_w: struct #ordered { | |
xyz: struct { | |
x, y, z: f32 | |
} | |
w: f32, | |
}, | |
using xy_zw: struct #ordered { | |
xy: struct { | |
x, y: f32 | |
} | |
zw: struct { | |
z, w: f32 | |
} | |
}, | |
using _yz_: struct #ordered { | |
pad1: f32, | |
using yz: struct { | |
y, z: f32 | |
}, | |
pad2: f32, | |
}, | |
} | |
v: Vec4; | |
v.x, v.y, v.z, v.w = 1.0, 2.0, 3.0, 4.0; | |
fmt.printf("v = %v, size_of(v) = %v\n", v, size_of(v)); | |
fmt.printf("v.x = %v, v.y = %v, v.z = %v, v.w = %v\n", v.x, v.y, v.z, v.w); | |
fmt.printf("v.xy = %v, v.yz = %v, v.zw = %v\n", v.xy, v.yz, v.zw); | |
fmt.printf("v.xyz = %v, v.yzw = %v\n", v.xyz, v.yzw); | |
fmt.printf("v.xyzw = %v\n", v.xyzw); | |
fmt.println(); | |
// Finally, you can use `using` to make a struct array-like (indexable): | |
Array :: struct(T: type, N: int) { | |
using values: [N]T, | |
}; | |
arr: Array(f64, 10); | |
arr[5] = 1.0; | |
fmt.printf("arr = %v\n", arr); | |
fmt.println(); | |
// Note, this also works for vector types and slices |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment