From ce3679aa45710261afa2e519cfc55164541643fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Roman=20Fro=C5=82ow?=
The code sample begins by adding Zig's Standard Library to the build using the {#link|@import#} builtin function.
The {#syntax#}@import("std"){#endsyntax#} function call creates a structure to represent the Standard Library.
- The code then makes a {#link|top-level declaration|Global Variables#} of a
+ The code then {#link|declares|Container level Variables#} a
{#link|constant identifier|Assignment#}, named std, for easy access to
Zig's standard library.
- Global variables are considered to be a top level declaration, which means that they are - order-independent and lazily analyzed. The initialization value of global variables is implicitly - {#link|comptime#}. If a global variable is {#syntax#}const{#endsyntax#} then its value is + Container level variables have static lifetime and are order-independent and lazily analyzed. + The initialization value of container level variables is implicitly + {#link|comptime#}. If a container level variable is {#syntax#}const{#endsyntax#} then its value is {#syntax#}comptime{#endsyntax#}-known, otherwise it is runtime-known.
- {#code_begin|test|global_variables#} + {#code_begin|test|container_level_variables#} var y: i32 = add(10, x); const x: i32 = add(12, 34); -test "global variables" { +test "container level variables" { try expect(x == 46); try expect(y == 56); } @@ -896,27 +896,51 @@ const std = @import("std"); const expect = std.testing.expect; {#code_end#}- Global variables may be declared inside a {#link|struct#}, {#link|union#}, or {#link|enum#}: + Container level variables may be declared inside a {#link|struct#}, {#link|union#}, or {#link|enum#}:
- {#code_begin|test|namespaced_global#} + {#code_begin|test|namespaced_container_level_variable#} const std = @import("std"); const expect = std.testing.expect; -test "namespaced global variable" { +test "namespaced container level variable" { try expect(foo() == 1235); try expect(foo() == 1236); } +const S = struct { + var x: i32 = 1234; +}; + fn foo() i32 { - const S = struct { - var x: i32 = 1234; - }; S.x += 1; return S.x; } {#code_end#} + {#header_close#} + + {#header_open|Static Local Variables#}- The {#syntax#}extern{#endsyntax#} keyword can be used to link against a variable that is exported + It is also possible to have local variables with static lifetime by using containers inside functions. +
+ {#code_begin|test|static_local_variable#} + const std = @import("std"); + const expect = std.testing.expect; + + test "static local variable" { + expect(foo() == 1235); + expect(foo() == 1236); + } + + fn foo() i32 { + const S = struct { + var x: i32 = 1234; + }; + S.x += 1; + return S.x; + } + {#code_end#} ++ The {#syntax#}extern{#endsyntax#} keyword or {#link|@extern#} builtin function can be used to link against a variable that is exported from another object. The {#syntax#}export{#endsyntax#} keyword or {#link|@export#} builtin function can be used to make a variable available to other objects at link time. In both cases, the type of the variable must be C ABI compatible. @@ -948,7 +972,7 @@ fn testTls(context: void) void { } {#code_end#}
- For {#link|Single Threaded Builds#}, all thread local variables are treated as {#link|Global Variables#}. + For {#link|Single Threaded Builds#}, all thread local variables are treated as regular {#link|Container Level Variables#}.
Thread local variables may not be {#syntax#}const{#endsyntax#}. @@ -2467,7 +2491,7 @@ test "dot product" { try expect(Vec3.dot(v1, v2) == 0.0); } -// Structs can have global declarations. +// Structs can have declarations. // Structs can have 0 fields. const Empty = struct { pub const PI = 3.14; @@ -5684,7 +5708,7 @@ test "@intToPtr for pointer to zero bit type" { {#header_open|usingnamespace#}
- {#syntax#}usingnamespace{#endsyntax#} is a top level declaration that imports all the public declarations of + {#syntax#}usingnamespace{#endsyntax#} is a declaration that imports all the public declarations of the operand, which must be a {#link|struct#}, {#link|union#}, or {#link|enum#}, into the current scope:
{#code_begin|test|usingnamespace#} @@ -5692,6 +5716,19 @@ usingnamespace @import("std"); test "using std namespace" { try testing.expect(true); +} + {#code_end#} ++ {#syntax#}usingnamespace{#endsyntax#} can also be used in containers: +
+ {#code_begin|test|usingnamespace_inside_struct#} +test "using namespace inside struct" { + const L = struct { + usingnamespace struct { + pub fn f() void {} + }; + }; + L.f(); } {#code_end#}@@ -6044,7 +6081,7 @@ test "fibonacci" {
- In the global scope (outside of any function), all expressions are implicitly + At container level (outside of any function), all expressions are implicitly {#syntax#}comptime{#endsyntax#} expressions. This means that we can use functions to initialize complex static data. For example:
@@ -8529,7 +8566,7 @@ fn List(comptime T: type) type { } {#code_end#}- When {#syntax#}@This(){#endsyntax#} is used at global scope, it returns a reference to the + When {#syntax#}@This(){#endsyntax#} is used at file scope, it returns a reference to the struct that corresponds to the current file.
{#header_close#} @@ -8744,7 +8781,7 @@ pub fn build(b: *Builder) void { {#header_open|Single Threaded Builds#}Zig has a compile option --single-threaded which has the following effects: