Multiline Strings Migration Guide
This guide helps developers migrate from regular strings to multiline strings and understand when and how to use this powerful feature in Harneet.
Overview
Multiline strings in Harneet use backtick delimiters (`) and provide a raw string format that preserves formatting and doesn't interpret escape sequences. They're perfect for SQL queries, HTML templates, JSON data, and configuration files.
When to Use Multiline Strings
✅ Perfect Use Cases
SQL Queries
| SQL Queries - Before and After |
|---|
| // Before: Hard to read and maintain
var query = "SELECT u.name, u.email, p.title FROM users u JOIN posts p ON u.id = p.author_id WHERE u.active = TRUE AND p.published = TRUE ORDER BY p.created_at DESC LIMIT 10"
// After: Clean and readable
var query = `
SELECT u.name, u.email, p.title
FROM users u
JOIN posts p ON u.id = p.author_id
WHERE u.active = TRUE
AND p.published = TRUE
ORDER BY p.created_at DESC
LIMIT 10
`
|
HTML Templates
| HTML Templates - Before and After |
|---|
| // Before: Escape sequences everywhere
var html = "<div class=\"container\">\n <h1>Welcome</h1>\n <p>Hello \"World\"!</p>\n</div>"
// After: Natural HTML formatting
var html = `<div class="container">
<h1>Welcome</h1>
<p>Hello "World"!</p>
</div>`
|
JSON Data
| JSON Data - Before and After |
|---|
| // Before: Difficult to read and edit
var json = "{\"name\": \"John\", \"email\": \"john@example.com\", \"preferences\": {\"theme\": \"dark\", \"notifications\": true}}"
// After: Properly formatted JSON
var json = `{
"name": "John",
"email": "john@example.com",
"preferences": {
"theme": "dark",
"notifications": true
}
}`
|
Configuration Files
| Configuration Files - Before and After |
|---|
| // Before: Hard to maintain
var config = "server:\n host: localhost\n port: 8080\ndatabase:\n host: db.example.com\n port: 5432"
// After: Clear YAML structure
var config = `
server:
host: localhost
port: 8080
database:
host: db.example.com
port: 5432
`
|
File Paths and Regular Expressions
| Paths and Regex - Before and After |
|---|
| // Before: Double backslashes needed
var windowsPath = "C:\\Users\\John\\Documents\\file.txt"
var regex = "\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}"
// After: Natural syntax
var windowsPath = `C:\Users\John\Documents\file.txt`
var regex = `\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}`
|
❌ When NOT to Use Multiline Strings
Simple Single-Line Text
| Simple Text - Use Regular Strings |
|---|
| // Use regular strings for simple text
var message = "Hello, World!" // ✅ Good
var message = `Hello, World!` // ❌ Unnecessary
|
When You Need Escape Sequences
| Escape Sequences - Use Regular Strings |
|---|
| // If you actually want a newline character in the string
var withNewline = "Line 1\nLine 2" // ✅ Creates actual newline
var withNewline = `Line 1\nLine 2` // ❌ Literal \n characters
|
Migration Examples
Example 1: SQL Query Migration
Before (Regular String)
| SQL Migration - Before |
|---|
| import fmt
function main() {
var createTable = "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL, email TEXT UNIQUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)"
fmt.Println("SQL:", createTable)
}
|
After (Multiline String)
| SQL Migration - After |
|---|
| import fmt
function main() {
var createTable = `
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
`
fmt.Println("SQL:", createTable)
}
|
Example 2: HTML Template Migration
Before (Regular String)
| HTML Migration - Before |
|---|
| import fmt
function main() {
var template = "<html><head><title>My Page</title></head><body><h1>Welcome</h1><p>This is a \"sample\" page.</p></body></html>"
fmt.Println(template)
}
|
After (Multiline String)
| HTML Migration - After |
|---|
| import fmt
function main() {
var template = `<html>
<head>
<title>My Page</title>
</head>
<body>
<h1>Welcome</h1>
<p>This is a "sample" page.</p>
</body>
</html>`
fmt.Println(template)
}
|
Example 3: Configuration Data Migration
Before (Regular String)
| Config Migration - Before |
|---|
| import fmt
function main() {
var config = "{\"server\": {\"host\": \"localhost\", \"port\": 8080}, \"database\": {\"host\": \"db.example.com\", \"port\": 5432, \"name\": \"myapp\"}}"
fmt.Println("Config:", config)
}
|
After (Multiline String)
| Config Migration - After |
|---|
| import fmt
function main() {
var config = `{
"server": {
"host": "localhost",
"port": 8080
},
"database": {
"host": "db.example.com",
"port": 5432,
"name": "myapp"
}
}`
fmt.Println("Config:", config)
}
|
Key Differences to Remember
Escape Sequences
| Regular String | Multiline String | Result |
"Line 1\nLine 2" | `Line 1\nLine 2` | Regular: Two lines Multiline: Literal \n |
"Tab\there" | `Tab\there` | Regular: Tab character Multiline: Literal \t |
"Quote: \"Hello\"" | `Quote: "Hello"` | Both: Quote: "Hello" |
Whitespace Handling
| Whitespace Handling |
|---|
| // Regular string - escape sequences processed
var regular = " Indented\n Text"
// Multiline string - exact formatting preserved
var multiline = ` Indented
Text`
// Both produce the same visual result, but multiline is more readable
|
Best Practices
1. Consistent Indentation
| Consistent Indentation |
|---|
| // ✅ Good: Consistent indentation
var sql = `
SELECT name, email
FROM users
WHERE active = TRUE
ORDER BY name
`
// ❌ Avoid: Inconsistent indentation
var sql = `
SELECT name, email
FROM users
WHERE active = TRUE
ORDER BY name
`
|
2. Leading/Trailing Whitespace
| Leading/Trailing Whitespace |
|---|
| // Be aware of leading/trailing whitespace
var withWhitespace = `
Content here
`
// If you don't want leading/trailing newlines, start/end on the same line
var withoutWhitespace = `Content here`
|
3. String Operations
| String Operations |
|---|
| import strings
// Multiline strings work with all string functions
var multilineText = `Line 1
Line 2
Line 3`
var length, _ = strings.Len(multilineText)
var upper, _ = strings.Upper(multilineText)
var lines, _ = strings.Split(multilineText, "\n") // Note: literal newline in multiline string
|
Common Gotchas
1. Literal vs Interpreted Characters
| Literal vs Interpreted |
|---|
| // This creates a literal \n, not a newline
var literal = `Line 1\nLine 2`
// This creates an actual newline
var interpreted = "Line 1\nLine 2"
// To get newlines in multiline strings, use actual line breaks
var actualNewlines = `Line 1
Line 2`
|
2. Backticks in Content
| Backticks in Content |
|---|
| // If you need literal backticks in your content, use regular strings
var withBackticks = "Use `backticks` for multiline strings"
// Or escape them in documentation contexts
var documentation = "Use `` ` `` for multiline strings"
|
3. String Concatenation
| String Concatenation |
|---|
| // Multiline strings can be concatenated like regular strings
var part1 = `First part
with multiple lines`
var part2 = `Second part
also multiline`
var combined = part1 + "\n" + part2 // Add explicit separator if needed
|
Multiline strings have the same performance characteristics as regular strings:
- Memory: No additional overhead compared to regular strings
- Processing: String operations work identically
- Compilation: No performance difference at compile time
Testing Your Migration
When migrating to multiline strings, test that:
- Output matches expectations: Verify the string content is what you expect
- String operations work: Test with functions like
strings.Len(), strings.Contains() - Integration works: Ensure the strings work correctly in your application context
| Testing Multiline Strings |
|---|
| import fmt
import strings
function testMultilineString() {
var original = "Line 1\nLine 2"
var multiline = `Line 1
Line 2`
// These should produce the same visual output
fmt.Println("Original:", original)
fmt.Println("Multiline:", multiline)
// Test string operations
var origLen, _ = strings.Len(original)
var multiLen, _ = strings.Len(multiline)
fmt.Printf("Lengths - Original: %d, Multiline: %d\n", origLen, multiLen)
}
|
Conclusion
Multiline strings are a powerful feature that can significantly improve code readability and maintainability, especially when working with formatted text like SQL, HTML, JSON, or configuration data. Use them when you need to preserve formatting and when the content would be difficult to read or maintain as a regular string with escape sequences.
Remember: multiline strings are raw strings that preserve exact formatting, while regular strings interpret escape sequences. Choose the right tool for your specific use case.