Repository URL to install this package:
|
Version:
1.6.5 ▾
|
XGo provides powerful and flexible string handling capabilities. Strings are sequences of characters used to represent text, and they are one of the most commonly used data types in programming.
XGo provides multiple ways to represent strings, from simple literals to complex Unicode characters.
In XGo, you can create strings using double quotes:
name := "Bob" message := "Hello, World!" empty := ""
XGo also supports raw string literals using backticks (`). Raw strings treat backslashes and other special characters literally, making them ideal for regular expressions, file paths, and multi-line text:
// Raw strings ignore escape sequences path := `C:\Users\Bob\Documents` // Backslashes are literal regex := `\d+\.\d+` // No need to escape backslashes // Multi-line raw strings multiline := `Line 1 Line 2 Line 3` // JSON or code snippets json := `{ "name": "Alice", "age": 30 }` // SQL queries query := `SELECT * FROM users WHERE age > 18 ORDER BY name`
Key differences between double-quoted and raw strings:
| Feature | Double-quoted "..." |
Raw (backtick) `...` |
|---|---|---|
| Escape sequences | Processed (\n, \t, etc.) |
Literal (ignored) |
| Multi-line | Requires \n |
Natural line breaks |
| Backslashes | Must escape \\ |
Literal \ |
| Interpolation | Supported ${...} |
Not supported |
| Use case | General strings, interpolation | Paths, regex, multi-line text |
// Comparison example escaped := "Line 1\nLine 2" // Two lines when printed raw := `Line 1\nLine 2` // Literal \n characters echo escaped // Output: // Line 1 // Line 2 echo raw // Output: // Line 1\nLine 2
XGo supports various escape sequences for special characters:
// Common escape sequences newline := "Line 1\nLine 2" // Newline tab := "Column1\tColumn2" // Tab quote := "She said \"Hello\"" // Double quote backslash := "Path: C:\\files" // Backslash // Octal escape notation \### where # is an octal digit octalChar := "\141a" // aa // Unicode can be specified as \u#### where # is a hex digit // It will be converted internally to its UTF-8 representation star := "\u2605" // ★ heart := "\u2665" // ♥
| Sequence | Description | Example |
|---|---|---|
\n |
Newline | "Line 1\nLine 2" |
\t |
Tab | "Name:\tAlice" |
\\ |
Backslash | "C:\\path" |
\" |
Double quote | "He said \"Hi\"" |
\### |
Octal character | "\141" (a) |
\u#### |
Unicode character | "\u2605" (★) |
String values are immutable in XGo. Once created, you cannot modify individual characters:
s := "hello 🌎" s[0] = `H` // Error: not allowed
To modify a string, you must create a new one:
s := "hello" s = "Hello" // OK: assigning a new string s = s + " world" // OK: creating a new concatenated string
Indexing a string returns a byte value (not a rune or another string):
name := "Bob" echo name[0] // 66 (ASCII value of 'B') echo name[1] // 111 (ASCII value of 'o') echo name[2] // 98 (ASCII value of 'b')
Warning: Indexing into multi-byte characters (like Chinese characters or emojis) will return individual bytes, which may not represent a complete character.
You can extract substrings using slice notation:
name := "Bob" echo name[1:3] // ob (from index 1 to 3, exclusive) echo name[:2] // Bo (from start to index 2) echo name[2:] // b (from index 2 to end) s := "Hello, World!" echo s[0:5] // Hello echo s[:5] // Hello (start defaults to 0) echo s[7:] // World! (end defaults to string length)
Slicing syntax:
s[start:end] - from index start to end (exclusive)s[:end] - from beginning to ends[start:] - from start to end of stringStrings can be easily converted to integers:
s := "12" a, err := s.int // Returns value and error (safe conversion) b := s.int! // Panics if s isn't a valid integer (unsafe conversion) // Example with error handling if num, err := s.int; err == nil { echo "Valid number:", num } else { echo "Invalid number" }
To convert other types to strings, use the .string property:
age := 10 ageStr := age.string echo "age = " + ageStr // age = 10 pi := 3.14159 piStr := pi.string echo "π = " + piStr // π = 3.14159
Use the + operator to concatenate strings:
name := "Bob" bobby := name + "by" echo bobby // Bobby s := "Hello " s += "world" echo s // Hello world // Multiple concatenations greeting := "Hello" + " " + "World" + "!" echo greeting // Hello World!
XGo operators require values of the same type on both sides. You cannot concatenate an integer directly to a string:
age := 10 echo "age = " + age // Error: not allowed
You must convert age to a string first:
age := 10 echo "age = " + age.string // age = 10
XGo supports string interpolation using ${expression} syntax, which provides a cleaner alternative to concatenation:
age := 10 echo "age = ${age}" // age = 10 name := "Alice" greeting := "Hello, ${name}!" echo greeting // Hello, Alice!
You can use any expression inside ${...}:
// Arithmetic expressions x := 5 y := 3 echo "${x} + ${y} = ${x + y}" // 5 + 3 = 8 // Function calls and method calls name := "bob" echo "Hello, ${name.toUpper}!" // Hello, BOB! // Complex example host := "example.com" page := 0 limit := 20 url := "https://${host}/items?page=${page+1}&limit=${limit}" echo url // https://example.com/items?page=1&limit=20
To include a literal $ in a string, use $$:
echo "Price: $$50" // Price: $50 echo "Total: $$${100 + 50}" // Total: $150
XGo provides built-in methods for common string operations. These methods do not modify the original string (strings are immutable) but return new strings.
You can get the length of a string using the len method:
name := "Bob" echo name.len // 3 chinese := "你好" echo chinese.len // 6 (bytes, not characters - each Chinese character is 3 bytes in UTF-8)
Important: len returns the number of bytes, not the number of characters. For strings containing non-ASCII characters (like Chinese, emojis), the byte length will be larger than the character count.
// Convert to uppercase echo "Hello".toUpper // HELLO echo "hello world".toUpper // HELLO WORLD // Convert to lowercase echo "Hello".toLower // hello echo "HELLO WORLD".toLower // hello world // Capitalize first letter of each word echo "hello world".capitalize // Hello World echo "the quick brown fox".capitalize // The Quick Brown Fox
// Repeat a string n times echo "XGo".repeat(3) // XGoXGoXGo echo "Ha".repeat(5) // HaHaHaHaHa echo "-".repeat(10) // ---------- // Useful for formatting separator := "=".repeat(40) echo separator echo "Title" echo separator
// Replace all occurrences echo "Hello".replaceAll("l", "L") // HeLLo echo "banana".replaceAll("a", "o") // bonono // Practical example text := "The quick brown fox" censored := text.replaceAll("fox", "***") echo censored // The quick brown ***
Join a list of strings into a single string with a separator:
// Join with comma fruits := ["apple", "banana", "cherry"] echo fruits.join(",") // apple,banana,cherry // Join with space words := ["Hello", "World"] echo words.join(" ") // Hello World // Join without separator letters := ["H", "e", "l", "l", "o"] echo letters.join("") // Hello // Practical example with newlines lines := ["Line 1", "Line 2", "Line 3"] text := lines.join("\n") echo text // Output: // Line 1 // Line 2 // Line 3
Split a string into a list of substrings using a separator:
// Split by delimiter subjects := "Math-English-Science-History" subjectList := subjects.split("-") echo subjectList // [Math English Science History] // Split by space sentence := "The quick brown fox" words := sentence.split(" ") echo words // [The quick brown fox] // Split CSV data csv := "Alice,30,Engineer" fields := csv.split(",") echo fields // [Alice 30 Engineer] // Process split results for field in fields { echo "Field:", field }
In XGo, strings can be traversed by character (rune) or by byte. Understanding the difference is crucial when working with non-ASCII characters.
len returns byte count, not character countUse for in loop to iterate over characters (runes):
// English text (1 byte per character) s := "Hello" for c in s { echo c } // Output: // H // e // l // l // o // Mixed text with Chinese characters s := "你好XGo" for c in s { echo c } // Output: // 你 // 好 // X // G // o
Use traditional index-based loop to iterate over bytes:
s := "Hello" for i := 0; i < len(s); i++ { echo s[i] // Prints byte values: 72, 101, 108, 108, 111 } // With non-ASCII characters s := "你好XGo" for i := 0; i < len(s); i++ { echo s[i] } // Outputs byte values (each Chinese character is 3 bytes) // For '你': 228, 189, 160 // For '好': 229, 165, 189 // For 'X': 88 // For 'G': 71 // For 'o': 111
⚠️ Important Warnings:
len() returns bytes, not character countfor c in s instead of index-based loops// Example: Chinese characters s := "你好" // WRONG: This returns byte count, not character count echo s.len // 6 (bytes) // WRONG: This returns part of a character echo s[0] // 228 (first byte of '你') // CORRECT: Count characters count := 0 for _ in s { count++ } echo count // 2 (characters) // CORRECT: Process characters for char in s { echo char // Prints: 你, then 好 }
// Process mixed text (need character iteration) mixed := "Hello你好" echo "Byte length:", mixed.len // 11 (5 ASCII + 6 for Chinese) charCount := 0 for _ in mixed { charCount++ } echo "Character count:", charCount // 7 // Extract characters correctly for i, char in mixed { echo "Character ${i}: ${char}" } // Output: // Character 0: H // Character 1: e // Character 2: l // Character 3: l // Character 4: o // Character 5: 你 // Character 8: 好
// Check if string is a valid integer input := "12345" if num, err := input.int; err == nil { echo "Valid number:", num } else { echo "Invalid number" } // Check string length username := "alice" if username.len < 3 { echo "Username too short" } else if username.len > 20 { echo "Username too long" } else { echo "Username OK" }
// Build formatted strings name := "Alice" age := 30 city := "New York" // Using interpolation profile := "Name: ${name}, Age: ${age}, City: ${city}" echo profile // Building multi-line strings header := "=".repeat(40) title := "User Profile" content := "${header}\n${title}\n${header}\nName: ${name}\nAge: ${age}\nCity: ${city}" echo content
// Parse CSV data csv := "Alice,30,Engineer,New York" fields := csv.split(",") name := fields[0] age := fields[1].int! job := fields[2] city := fields[3] echo "Name: ${name}, Age: ${age}, Job: ${job}, City: ${city}" // Parse key-value pairs config := "host=localhost;port=8080;debug=true" pairs := config.split(";") settings := {} for pair in pairs { parts := pair.split("=") key := parts[0] value := parts[1] settings[key] = value } echo settings // map[host:localhost port:8080 debug:true]
// Email template func generateEmail(name, action, link string) string { return "Hello ${name},\n\nPlease click the link below to ${action}:\n${link}\n\nBest regards,\nThe Team" } email := generateEmail("Alice", "verify your email", "https://example.com/verify") echo email
// Word count text := "The quick brown fox jumps over the lazy dog" words := text.split(" ") echo "Word count:", words.len // Capitalize each word capitalized := [] for word in words { capitalized = append(capitalized, word.capitalize) } result := capitalized.join(" ") echo result // The Quick Brown Fox Jumps Over The Lazy Dog // Remove extra spaces messyText := " Too many spaces " cleaned := [s for s in messyText.split(" ") if s != ""].join(" ") echo cleaned // Too many spaces
// Building a URL with query parameters func buildURL(base string, params map[string]any) string { if params.len == 0 { return base } queryParts := [] for key, value in params { queryParts = append(queryParts, "${key}=${value}") } return "${base}?${queryParts.join("&")}" } url := buildURL("https://api.example.com/search", { "q": "xgo", "page": 1, "limit": 20, }) echo url // https://api.example.com/search?q=xgo&page=1&limit=20 // Building a report func buildReport(title string, items []string) string { separator := "=".repeat(50) header := "${separator}\n${title}\n${separator}" itemList := [] for i, item in items { itemList = append(itemList, "${i+1}. ${item}") } return "${header}\n${itemList.join("\n")}" } report := buildReport("Task List", ["Review code", "Write tests", "Update docs"]) echo report
"${expr}") instead of concatenation for better readability.string method to convert other types to stringsfor c in s) when processing text with non-ASCII characters.toUpper, .toLower, etc.) for case-insensitive operationsAvoid excessive concatenation in loops: Build string slices and join them instead
// Less efficient result := "" for i := 0; i < 1000; i++ { result += "item${i}," } // More efficient parts := [] for i := 0; i < 1000; i++ { parts = append(parts, "item${i}") } result := parts.join(",")
Use string interpolation: It's more efficient than multiple concatenations
// Less efficient message := "Hello, " + name + "! You are " + age.string + " years old." // More efficient message := "Hello, ${name}! You are ${age} years old."
Reuse string slices: When splitting strings multiple times, consider reusing slices
Consider byte operations: For performance-critical ASCII-only operations, byte-level processing can be faster
Preallocate when building large strings: If you know the approximate size, preallocate capacity