| ... | @@ -258,7 +258,7 @@ pub fn main() !void { | ... | @@ -258,7 +258,7 @@ pub fn main() !void { |
| 258 | <p> | 258 | <p> |
| 259 | The code sample begins by adding Zig's Standard Library to the build using the {#link|@import#} builtin function. | 259 | The code sample begins by adding Zig's Standard Library to the build using the {#link|@import#} builtin function. |
| 260 | The {#syntax#}@import("std"){#endsyntax#} function call creates a structure to represent the Standard Library. | 260 | The {#syntax#}@import("std"){#endsyntax#} function call creates a structure to represent the Standard Library. |
| 261 | The code then makes a {#link|top-level declaration|Global Variables#} of a | 261 | The code then {#link|declares|Container level Variables#} a |
| 262 | {#link|constant identifier|Assignment#}, named <code>std</code>, for easy access to | 262 | {#link|constant identifier|Assignment#}, named <code>std</code>, for easy access to |
| 263 | <a href="https://github.com/ziglang/zig/wiki/FAQ#where-is-the-documentation-for-the-zig-standard-library">Zig's standard library</a>. | 263 | <a href="https://github.com/ziglang/zig/wiki/FAQ#where-is-the-documentation-for-the-zig-standard-library">Zig's standard library</a>. |
| 264 | </p> | 264 | </p> |
| ... | @@ -802,7 +802,7 @@ const hello_world_in_c = | ... | @@ -802,7 +802,7 @@ const hello_world_in_c = |
| 802 | const x = 1234; | 802 | const x = 1234; |
| 803 | | 803 | |
| 804 | fn foo() void { | 804 | fn foo() void { |
| 805 | // It works at global scope as well as inside functions. | 805 | // It works at file scope as well as inside functions. |
| 806 | const y = 5678; | 806 | const y = 5678; |
| 807 | | 807 | |
| 808 | // Once assigned, an identifier cannot be changed. | 808 | // Once assigned, an identifier cannot be changed. |
| ... | @@ -872,18 +872,18 @@ test "init with undefined" { | ... | @@ -872,18 +872,18 @@ test "init with undefined" { |
| 872 | {#syntax#}var{#endsyntax#} when declaring a variable. This causes less work for both | 872 | {#syntax#}var{#endsyntax#} when declaring a variable. This causes less work for both |
| 873 | humans and computers to do when reading code, and creates more optimization opportunities. | 873 | humans and computers to do when reading code, and creates more optimization opportunities. |
| 874 | </p> | 874 | </p> |
| 875 | {#header_open|Global Variables#} | 875 | {#header_open|Container Level Variables#} |
| 876 | <p> | 876 | <p> |
| 877 | Global variables are considered to be a top level declaration, which means that they are | 877 | Container level variables have static lifetime and are order-independent and lazily analyzed. |
| 878 | order-independent and lazily analyzed. The initialization value of global variables is implicitly | 878 | The initialization value of container level variables is implicitly |
| 879 | {#link|comptime#}. If a global variable is {#syntax#}const{#endsyntax#} then its value is | 879 | {#link|comptime#}. If a container level variable is {#syntax#}const{#endsyntax#} then its value is |
| 880 | {#syntax#}comptime{#endsyntax#}-known, otherwise it is runtime-known. | 880 | {#syntax#}comptime{#endsyntax#}-known, otherwise it is runtime-known. |
| 881 | </p> | 881 | </p> |
| 882 | {#code_begin|test|global_variables#} | 882 | {#code_begin|test|container_level_variables#} |
| 883 | var y: i32 = add(10, x); | 883 | var y: i32 = add(10, x); |
| 884 | const x: i32 = add(12, 34); | 884 | const x: i32 = add(12, 34); |
| 885 | | 885 | |
| 886 | test "global variables" { | 886 | test "container level variables" { |
| 887 | try expect(x == 46); | 887 | try expect(x == 46); |
| 888 | try expect(y == 56); | 888 | try expect(y == 56); |
| 889 | } | 889 | } |
| ... | @@ -896,27 +896,51 @@ const std = @import("std"); | ... | @@ -896,27 +896,51 @@ const std = @import("std"); |
| 896 | const expect = std.testing.expect; | 896 | const expect = std.testing.expect; |
| 897 | {#code_end#} | 897 | {#code_end#} |
| 898 | <p> | 898 | <p> |
| 899 | Global variables may be declared inside a {#link|struct#}, {#link|union#}, or {#link|enum#}: | 899 | Container level variables may be declared inside a {#link|struct#}, {#link|union#}, or {#link|enum#}: |
| 900 | </p> | 900 | </p> |
| 901 | {#code_begin|test|namespaced_global#} | 901 | {#code_begin|test|namespaced_container_level_variable#} |
| 902 | const std = @import("std"); | 902 | const std = @import("std"); |
| 903 | const expect = std.testing.expect; | 903 | const expect = std.testing.expect; |
| 904 | | 904 | |
| 905 | test "namespaced global variable" { | 905 | test "namespaced container level variable" { |
| 906 | try expect(foo() == 1235); | 906 | try expect(foo() == 1235); |
| 907 | try expect(foo() == 1236); | 907 | try expect(foo() == 1236); |
| 908 | } | 908 | } |
| 909 | | 909 | |
| | 910 | const S = struct { |
| | 911 | var x: i32 = 1234; |
| | 912 | }; |
| | 913 | |
| 910 | fn foo() i32 { | 914 | fn foo() i32 { |
| 911 | const S = struct { | | |
| 912 | var x: i32 = 1234; | | |
| 913 | }; | | |
| 914 | S.x += 1; | 915 | S.x += 1; |
| 915 | return S.x; | 916 | return S.x; |
| 916 | } | 917 | } |
| | 918 | {#code_end#} |
| | 919 | {#header_close#} |
| | 920 | |
| | 921 | {#header_open|Static Local Variables#} |
| | 922 | <p> |
| | 923 | It is also possible to have local variables with static lifetime by using containers inside functions. |
| | 924 | </p> |
| | 925 | {#code_begin|test|static_local_variable#} |
| | 926 | const std = @import("std"); |
| | 927 | const expect = std.testing.expect; |
| | 928 | |
| | 929 | test "static local variable" { |
| | 930 | expect(foo() == 1235); |
| | 931 | expect(foo() == 1236); |
| | 932 | } |
| | 933 | |
| | 934 | fn foo() i32 { |
| | 935 | const S = struct { |
| | 936 | var x: i32 = 1234; |
| | 937 | }; |
| | 938 | S.x += 1; |
| | 939 | return S.x; |
| | 940 | } |
| 917 | {#code_end#} | 941 | {#code_end#} |
| 918 | <p> | 942 | <p> |
| 919 | The {#syntax#}extern{#endsyntax#} keyword can be used to link against a variable that is exported | 943 | The {#syntax#}extern{#endsyntax#} keyword or {#link|@extern#} builtin function can be used to link against a variable that is exported |
| 920 | from another object. The {#syntax#}export{#endsyntax#} keyword or {#link|@export#} builtin function | 944 | from another object. The {#syntax#}export{#endsyntax#} keyword or {#link|@export#} builtin function |
| 921 | can be used to make a variable available to other objects at link time. In both cases, | 945 | can be used to make a variable available to other objects at link time. In both cases, |
| 922 | the type of the variable must be C ABI compatible. | 946 | the type of the variable must be C ABI compatible. |
| ... | @@ -948,7 +972,7 @@ fn testTls(context: void) void { | ... | @@ -948,7 +972,7 @@ fn testTls(context: void) void { |
| 948 | } | 972 | } |
| 949 | {#code_end#} | 973 | {#code_end#} |
| 950 | <p> | 974 | <p> |
| 951 | For {#link|Single Threaded Builds#}, all thread local variables are treated as {#link|Global Variables#}. | 975 | For {#link|Single Threaded Builds#}, all thread local variables are treated as regular {#link|Container Level Variables#}. |
| 952 | </p> | 976 | </p> |
| 953 | <p> | 977 | <p> |
| 954 | Thread local variables may not be {#syntax#}const{#endsyntax#}. | 978 | Thread local variables may not be {#syntax#}const{#endsyntax#}. |
| ... | @@ -2467,7 +2491,7 @@ test "dot product" { | ... | @@ -2467,7 +2491,7 @@ test "dot product" { |
| 2467 | try expect(Vec3.dot(v1, v2) == 0.0); | 2491 | try expect(Vec3.dot(v1, v2) == 0.0); |
| 2468 | } | 2492 | } |
| 2469 | | 2493 | |
| 2470 | // Structs can have global declarations. | 2494 | // Structs can have declarations. |
| 2471 | // Structs can have 0 fields. | 2495 | // Structs can have 0 fields. |
| 2472 | const Empty = struct { | 2496 | const Empty = struct { |
| 2473 | pub const PI = 3.14; | 2497 | pub const PI = 3.14; |
| ... | @@ -5684,7 +5708,7 @@ test "@intToPtr for pointer to zero bit type" { | ... | @@ -5684,7 +5708,7 @@ test "@intToPtr for pointer to zero bit type" { |
| 5684 | | 5708 | |
| 5685 | {#header_open|usingnamespace#} | 5709 | {#header_open|usingnamespace#} |
| 5686 | <p> | 5710 | <p> |
| 5687 | {#syntax#}usingnamespace{#endsyntax#} is a top level declaration that imports all the public declarations of | 5711 | {#syntax#}usingnamespace{#endsyntax#} is a declaration that imports all the public declarations of |
| 5688 | the operand, which must be a {#link|struct#}, {#link|union#}, or {#link|enum#}, into the current scope: | 5712 | the operand, which must be a {#link|struct#}, {#link|union#}, or {#link|enum#}, into the current scope: |
| 5689 | </p> | 5713 | </p> |
| 5690 | {#code_begin|test|usingnamespace#} | 5714 | {#code_begin|test|usingnamespace#} |
| ... | @@ -5692,6 +5716,19 @@ usingnamespace @import("std"); | ... | @@ -5692,6 +5716,19 @@ usingnamespace @import("std"); |
| 5692 | | 5716 | |
| 5693 | test "using std namespace" { | 5717 | test "using std namespace" { |
| 5694 | try testing.expect(true); | 5718 | try testing.expect(true); |
| | 5719 | } |
| | 5720 | {#code_end#} |
| | 5721 | <p> |
| | 5722 | {#syntax#}usingnamespace{#endsyntax#} can also be used in containers: |
| | 5723 | </p> |
| | 5724 | {#code_begin|test|usingnamespace_inside_struct#} |
| | 5725 | test "using namespace inside struct" { |
| | 5726 | const L = struct { |
| | 5727 | usingnamespace struct { |
| | 5728 | pub fn f() void {} |
| | 5729 | }; |
| | 5730 | }; |
| | 5731 | L.f(); |
| 5695 | } | 5732 | } |
| 5696 | {#code_end#} | 5733 | {#code_end#} |
| 5697 | <p> | 5734 | <p> |
| ... | @@ -6044,7 +6081,7 @@ test "fibonacci" { | ... | @@ -6044,7 +6081,7 @@ test "fibonacci" { |
| 6044 | </p> | 6081 | </p> |
| 6045 | | 6082 | |
| 6046 | <p> | 6083 | <p> |
| 6047 | In the global scope (outside of any function), all expressions are implicitly | 6084 | At container level (outside of any function), all expressions are implicitly |
| 6048 | {#syntax#}comptime{#endsyntax#} expressions. This means that we can use functions to | 6085 | {#syntax#}comptime{#endsyntax#} expressions. This means that we can use functions to |
| 6049 | initialize complex static data. For example: | 6086 | initialize complex static data. For example: |
| 6050 | </p> | 6087 | </p> |
| ... | @@ -8520,7 +8557,7 @@ fn List(comptime T: type) type { | ... | @@ -8520,7 +8557,7 @@ fn List(comptime T: type) type { |
| 8520 | } | 8557 | } |
| 8521 | {#code_end#} | 8558 | {#code_end#} |
| 8522 | <p> | 8559 | <p> |
| 8523 | When {#syntax#}@This(){#endsyntax#} is used at global scope, it returns a reference to the | 8560 | When {#syntax#}@This(){#endsyntax#} is used at file scope, it returns a reference to the |
| 8524 | struct that corresponds to the current file. | 8561 | struct that corresponds to the current file. |
| 8525 | </p> | 8562 | </p> |
| 8526 | {#header_close#} | 8563 | {#header_close#} |
| ... | @@ -8735,7 +8772,7 @@ pub fn build(b: *Builder) void { | ... | @@ -8735,7 +8772,7 @@ pub fn build(b: *Builder) void { |
| 8735 | {#header_open|Single Threaded Builds#} | 8772 | {#header_open|Single Threaded Builds#} |
| 8736 | <p>Zig has a compile option <code>--single-threaded</code> which has the following effects:</p> | 8773 | <p>Zig has a compile option <code>--single-threaded</code> which has the following effects:</p> |
| 8737 | <ul> | 8774 | <ul> |
| 8738 | <li>All {#link|Thread Local Variables#} are treated as {#link|Global Variables#}.</li> | 8775 | <li>All {#link|Thread Local Variables#} are treated as regular {#link|Container Level Variables#}.</li> |
| 8739 | <li>The overhead of {#link|Async Functions#} becomes equivalent to function call overhead.</li> | 8776 | <li>The overhead of {#link|Async Functions#} becomes equivalent to function call overhead.</li> |
| 8740 | <li>The {#syntax#}@import("builtin").single_threaded{#endsyntax#} becomes {#syntax#}true{#endsyntax#} | 8777 | <li>The {#syntax#}@import("builtin").single_threaded{#endsyntax#} becomes {#syntax#}true{#endsyntax#} |
| 8741 | and therefore various userland APIs which read this variable become more efficient. | 8778 | and therefore various userland APIs which read this variable become more efficient. |