Skip to content

proposal: spec: add simple string interpolation similar to Swift #57616

Closed as not planned
@ianlancetaylor

Description

@ianlancetaylor

I propose a simple version of string interpolation similar to that in Swift. This is a simpler version of #34174 and #50554.

Proposal

In string literals we permit a new escape sequence \(. A valid \( must be followed a expression and a trailing ). Any unquoted ( in the expression must be balanced by a ) so that the compiler can locate the ) that terminates the \(.

The expression is evaluated in the context of the string literal. If it is not valid, the compiler reports an error. Multiple \( expressions in the string literal are evaluated from left to right.

The expression must evaluate to a single value. If the type of that value has a method String() string, that method is called to get a string value. Otherwise the expression must be a string, integer, floating-point, complex, or boolean value. Values of other types will be reported as an error.

  1. If the expression has a string type, it is used as is.
  2. If the expression is a constant expression it is converted (as described below) to an untyped string constant.
  3. Otherwise the expression is converted (as described below) to a non-constant value of type string.

The original string "prefix\(expression)suffix" is then replaced by the expression ("prefix" + expressionAsString + "suffix").

Examples

    // Prints something like "Ken Thompson is 79 years old".
    fmt.Println("\(person.Name()) is \(person.Age()) years old")
    // Prints something like "The time is 2023-01-04 16:22:01.204034106 -0800 PST".
    // Note: calls the String method of time.Time.
    fmt.Println("The time is \(time.Now().Round(0))")

Formatting

Integer values are converted to strings in the obvious way.

Floating-point values are converted to strings with the equivalent of strconv.FormatFloat(f, 'g', prec, -1). This will need to be spelled out in the spec.

Complex values are converted to strings by converting the real and imaginary parts to R and I as with any float, and producing R+Ii or R-Ii.

Boolean values are converted to either "true" or "false".

Values of other types are not permitted.

Commentary

String interpolation is useful to avoid mistakes in complex formatting, as discussed in the earlier issues.

The earlier issues were caught up in complexity due to the desire to control formatting. However, 1) we already have fmt.Sprintf for arbitrary formatting; 2) even with simple string interpolation we can do formatting by writing code like "The average of \(len(values)) is \(strconv.FormatFloat(average, 'f', 32, 2))".

The syntax \(EXPR) is borrowed from Swift.

The type of the result ensures that interpolating variable values into a string can't produce an untyped string constant, but can only produce a non-constant string value. This will avoid implicit type conversions.

This proposal is backward compatible as currently using \( in a string causes a compilation error.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions