Skip to content

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
1
2
3
4
5
6
7
8
// 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
1
2
3
4
5
6
7
// 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
1
2
3
// 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
1
2
3
// 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
1
2
3
4
5
6
7
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
1
2
3
4
5
6
7
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
1
2
3
4
5
6
7
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
1
2
3
4
5
6
7
8
// 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
1
2
3
4
5
6
7
// 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
1
2
3
4
5
6
7
8
9
// 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
1
2
3
4
5
// 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
1
2
3
4
5
6
7
8
// 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

Performance Considerations

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:

  1. Output matches expectations: Verify the string content is what you expect
  2. String operations work: Test with functions like strings.Len(), strings.Contains()
  3. 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.