Skip to main content
A String in Dart is an immutable sequence of UTF-16 code units. It is an instance of the String class in the dart:core library and serves as the primary data type for textual information.

Internal Representation and Encoding

Dart strings are encoded using UTF-16.
  • Code Units: The fundamental elements of the string are 16-bit integers.
  • Length: The length property reflects the number of 16-bit code units. This count may differ from the number of perceived characters (grapheme clusters) if the string contains:
    • Surrogate Pairs: Characters outside the Basic Multilingual Plane (BMP), such as emojis or certain musical symbols, which require two code units.
    • Combining Characters: Diacritics or accents applied to a base character (e.g., e + ´).
  • Runes: The runes property exposes the string as an iterable of Unicode code points.
void main() {
  // Surrogate Pair Example (Musical Clef)
  const String clef = '\u{1D11E}'; 
  print(clef.length);       // 2 (Two 16-bit code units)
  print(clef.runes.length); // 1 (One Unicode code point)

  // Combining Character Example (e + combining acute accent)
  const String combined = 'e\u0301'; 
  print(combined);          // é
  print(combined.length);   // 2 (Base char + combining char)
}

Immutability

Strings in Dart are immutable. Once a string object is allocated, its content cannot be altered. Methods that appear to modify a string (such as substring, toLowerCase, or replaceAll) return a new String instance rather than mutating the original. For mutable character sequences, use the StringBuffer class.

Literal Syntax

Dart provides several syntactic forms for defining string literals.

Quoting

String literals may be enclosed in single quotes (') or double quotes ("). Both are functionally identical.
String s1 = 'Single quotes are standard.';
String s2 = "Double quotes are valid.";
String s3 = 'It\'s easy to escape delimiters.';
String s4 = "It's also easy to nest quotes.";

Multi-line Strings

Triple quotes (''' or """) define multi-line strings. These literals preserve newlines and indentation exactly as they appear in the source code.
String query = '''
SELECT id, name
FROM users
WHERE active = true
''';

Raw Strings

Prefixing a string literal with r creates a raw string. In this mode, escape sequences (such as \n or \t) are ignored and treated as literal characters.
// Interprets \n as a newline control character
String normal = 'Line 1\nLine 2'; 

// Interprets \n as two distinct characters: '\' and 'n'
String raw = r'Line 1\nLine 2'; 

String Interpolation

Dart supports string interpolation via the $ syntax, allowing expressions to be evaluated and embedded within a string literal.
  • Simple Identifiers: $variableName
  • Complex Expressions: ${expression}
The toString() method is implicitly invoked on the interpolated object.
int count = 5;
String item = 'widget';

// Identifier interpolation
String s1 = '$count $item'; 

// Expression interpolation
String s2 = '${item.toUpperCase()} count is ${count + 10}'; 

Compile-Time Concatenation

Adjacent string literals are automatically concatenated by the compiler. This feature applies strictly to literals, not variables or expressions.
// Valid: Concatenated at compile time
const String s = 'String ' 'concatenation '
                 'works even over line breaks.';

// Invalid: Variables require the + operator or interpolation
// String s2 = variable1 ' ' variable2; 

Equality

Dart distinguishes between structural equality and identity.
  • Structural Equality (==): The String class overrides the == operator to compare the sequence of code units. Two strings are equal if they contain the exact same sequence of UTF-16 code units.
  • Identity (identical()): The identical() function checks if two references point to the same underlying object.
Platform Differences:
  • Dart VM: Strings are objects. While compile-time constants are interned (canonicalized), dynamically constructed strings with identical content may exist as distinct objects in memory.
  • Dart Web (JavaScript): Strings are compiled to JavaScript primitive strings. Because JavaScript treats strings as value types, identical() behaves effectively the same as == for strings.
void main() {
  String a = 'hello';
  
  // Dynamic construction
  String suffix = 'lo';
  String b = 'hel' + suffix;

  // Checks content equality (Always true if content matches)
  print(a == b); // true

  // Checks reference equality
  // Result is platform dependent:
  // - Dart VM: false (Different memory addresses)
  // - Web (JS): true (Primitive value comparison)
  print(identical(a, b)); 
}
Master Dart with Deep Grasping Methodology!Learn More