LEVIATHAN v962456e · 962456eee1

Lexical

Char literals

A single-quoted literal becomes a char when the context expects one and it holds exactly one Unicode scalar.

since 0.1.0-alpha.1linuxwindowswasm

Description

The language has no separate char literal syntax. A single-quoted literal is a string by default, exactly like a double-quoted one. It is re-typed to char when two things are true:

  • the type expected at that point is char, and
  • the decoded literal is exactly one Unicode scalar.

char c = 'a'; is a char. string s = 'a'; is a string. A double-quoted literal is never a char.

Escapes work in char literals: '\n', '\t', '\x41' and '\u{1F600}' are all single scalars.

Char literals in typed contexts

char c = 'a';
char tab = '\t';
char hex = '\x41';
char smile = '\u{1F600}';
console.writeln(c.code());
console.writeln(tab.code());
console.writeln(hex);
console.writeln(smile.code());
console.writeln(c == 'a');
console.writeln(c < 'b');
97
9
A
128512
true
true

Rules

  • A char holds one Unicode scalar (0 to 0x10FFFF, surrogates excluded). A declared char that is never assigned holds scalar 0.
  • A single-quoted literal becomes a char in these contexts: a declaration whose type is char (or char?), a comparison against a char operand (c == 'a'), a match arm over a char subject, a return in a function that returns char, and an argument passed to a char parameter.
  • The literal must hold exactly one scalar. char c = 'ab'; and char c = ''; are compile errors ("cannot initialize 'c' with 'string'"). char c = "a"; is also an error.
  • A literal compared against a string stays a string. string s = 'a'; s == 'a' compares two strings.
  • When both f(char) and f(string) exist, a bare literal argument always chooses f(string). To call the char overload, pass a value that already has type char.
  • A triple-quoted literal is always a string, even with one scalar inside.
  • ==, !=, <, <=, > and >= compare chars by scalar value. There is no arithmetic on char; convert with code() first.

Examples

Target typing in a return, in a match arm and in an overloaded call:

Where a literal becomes a char

char grade(int score) {
    if (score >= 90) {
        return 'A';
    }
    return 'F';
}

void classify(char x) {
    match (x) {
        'a' => console.writeln("the letter a");
        else => console.writeln("something else");
    }
}

void describe(char x) {
    console.writeln("char overload");
}

void describe(string x) {
    console.writeln("string overload");
}

console.writeln(grade(95));
classify('a');
classify('z');
describe('x');
char c = 'x';
describe(c);
describe("x");
A
the letter a
something else
string overload
char overload
string overload

A declared char with no initializer holds the scalar 0:

char blank;
console.writeln(blank.code());
not run — blocked by an open compiler bug

The program prints 0. The compiled backend currently prints an empty line instead.

An inferred variable stays a string, because nothing asks for a char:

A literal with no char context is a string

void show() {
    var s = 'a';
    console.writeln(s.length());
    string t = 'a';
    console.writeln(t == 'a');
}
show();
1
true

Notes

The methods of char, such as code() and isDigit(), are documented in std.char.

See also

  • char — A single Unicode character, stored as one code point.
  • String literals — Quoted strings, escapes, ${} interpolation, raw r"..." strings and triple-quoted multiline strings.