Values
$ ./values
1 + 1 = 2
7.0 / 3.0 = 2.33333325e+00
false
true
false
optional 1
type: ?[]const u8
value: null
optional 2
type: ?[]const u8
value: hi
error union 1
type: anyerror!i32
value: error.ArgNotFound
error union 2
type: anyerror!i32
value: 1234
In addition to the integer types above, arbitrary bit-width integers can be referenced by using an identifier of i
or u followed by digits. For example, the identifier i7
refers to a signed 7-bit integer. The maximum allowed bit-width of an integer type is 65535
.
See also:
See also:
String literals are UTF-8 encoded byte arrays.
Character literals have type comptime_int
, the same as Integer Literals. All are valid in both string literals and character literals. Once https://github.com/ziglang/zig/issues/2097 is implemented, character literals will be allowed to have a single UTF-8 encoded codepoint.
test.zig
const assert = @import("std").debug.assert;
const mem = @import("std").mem;
test "string literals" {
// In Zig a string literal is an array of bytes.
const normal_bytes = "hello";
assert(@typeOf(normal_bytes) == [5]u8);
assert(normal_bytes.len == 5);
assert(normal_bytes[1] == 'e');
assert('e' == '\x65');
assert('\U01f4a9' == 128169);
assert(mem.eql(u8, "hello", "h\x65llo"));
// A C string literal is a null terminated pointer.
const null_terminated_bytes = c"hello";
assert(@typeOf(null_terminated_bytes) == [*]const u8);
assert(null_terminated_bytes[5] == 0);
}
$ zig test test.zig
Test 1/1 string literals...OK
All tests passed.
See also:
Multiline string literals have no escapes and can span across multiple lines. To start a multiline string literal, use the \
token. Just like a comment, the string literal goes until the end of the line. The end of the line is not included in the string literal. However, if the next line begins with \
then a newline is appended and the string literal continues.
For a multiline C string literal, prepend c
to each \
:
const c_string_literal =
c\\#include <stdio.h>
c\\
c\\int main(int argc, char **argv) {
c\\ printf("hello world\n");
c\\ return 0;
c\\}
;
In this example the variable c_string_literal
has type [*]const u8
and has a terminating null byte.
See also:
Use the const
keyword to assign a value to an identifier:
test.zig
const x = 1234;
fn foo() void {
// It works at global scope as well as inside functions.
const y = 5678;
// Once assigned, an identifier cannot be changed.
y += 1;
}
test "assignment" {
foo();
}
$ zig test test.zig
/home/andy/dev/zig/docgen_tmp/test.zig:8:7: error: cannot assign to constant
y += 1;
^
const
applies to all of the bytes that the identifier immediately addresses. Pointers have their own const-ness.
test.zig
$ zig test test.zig
Test 1/1 var...OK
All tests passed.
Variables must be initialized:
test.zig
test "initialization" {
var x: i32;
x = 1;
}
$ zig test test.zig
/home/andy/dev/zig/docgen_tmp/test.zig:2:5: error: variables must be initialized
var x: i32;
^
/home/andy/dev/zig/docgen_tmp/test.zig:4:5: error: use of undeclared identifier 'x'
x = 1;
^
Use undefined
to leave variables uninitialized:
test.zig
$ zig test test.zig
Test 1/1 init with undefined...OK
undefined
can be to any type. Once this happens, it is no longer possible to detect that the value is undefined
. undefined
means the value could be anything, even something that is nonsense according to the type. Translated into English, undefined
means "Not a meaningful value. Using this value would be a bug. The value will be unused, or overwritten before being used."
In Debug mode, Zig writes 0xaa
bytes to undefined memory. This is to catch bugs early, and to help detect use of undefined memory in a debugger.