Skip to content

Single-character String literal (int type) #11704

Open
@Ivorforce

Description

@Ivorforce

Describe the project you are working on

Godot internals.

Describe the problem or limitation you are having in your project

GDScript does not have a convenient way to express 'single character' values.
Ideally, it would have a literal type for them.

Single characters are most useful for their performance benefits, because they do not allocate memory (as opposed to String).

Some existing APIs already use single characters as arguments or return types (int type). It is currently inconvenient to call them (a is unicode 97):

  • string.get_slicec(97, 0) (ref)
  • input.is_key_label_pressed(97) (ref)
  • string.unicode_at(0) == 97 (ref)
  • Adjust functions that should already take single characters but are currently taking string, e.g. lpad: string.lpadc(97)
    • Changing input behavior would be better, but would break compatibility (5.0+)
  • String.chr(97) (ref)
    • Unlikely to be useful in this configuration as you can just use "a", but may be used transitively (through functions).

Describe the feature / enhancement and how it helps to overcome the problem or limitation

There should be a single-character literal for GDScript. Since GDScript uses int to describe characters in existing APIs, it would evaluate to int (UTF-32).

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

I propose the following syntax (analogous to others using String prefixes):

# Type is int
var char := c"a"  # Yields 97
var char := c'a'  # Yields 97

# Edge cases
var char := c"'"  # Valid, yields ' (39)
var char := c'"'  # Valid, yields " (34)
var char := c"\""  # Valid, yields " (34)
# Careful: Some characters are 1 char in UTF-32, but multiple chars in UTF-8 / UTF-16.
var char := c"Ä"  # Valid, yields Ä (196)
# Unlikely to be useful, could use var char := 0x2122 instead
var char := c"\u2122"  # Valid, yields ™ (8482 / 0x2122)

# Erroneous Use
var chars := c"aa" # Error: Expected one character in single-character literal, found string of size 2.
var chars := c"" # Error: Expected one character in single-character literal, found string of size 0.
# Emoji are often encoded using multiple characters.
var chars := c"👨🏻‍🦱" # Error: Expected one character in single-character literal, found string of size 7.

# Examples (each equal)
string.get_slicec(97, 0)
string.get_slicec(c"a", 0)

input.is_key_label_pressed(Key.KEY_A)
input.is_key_label_pressed(65)
input.is_key_label_pressed(c"A")

string.unicode_at(0) == 97
string.unicode_at(0) == c"a"

# Note: This function doesn't exist (yet?)
string.lpad("a")
string.lpadc(97)
string.lpadc(c"a")

"a"
String.chr(97)
String.chr(c"a")

If this enhancement will not be used often, can it be worked around with a few lines of script?

It is possible to use unicode value literals:

var char := 97  # a

These can be looked up on sites like unicodelookup.com.
It is also possible to use GDScript:

var char := "a".unicode_at(0)

However, this is slow.

Is there a reason why this should be core and not an add-on in the asset library?

It's GDScript syntax.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions