@@ -709,45 +709,49 @@ public protocol ExpressibleByDictionaryLiteral {
709
709
/// print(message)
710
710
/// // Prints "One cookie: $2, 3 cookies: $6."
711
711
///
712
- /// Extending default interpolation behavior
713
- /// ========================================
714
- ///
715
- /// Clients which want to add new interpolation behavior to existing types
716
- /// should extend `DefaultStringInterpolation`, the type which implements
717
- /// interpolation for types like `String` and `Substring`, to add an overload of
718
- /// `appendInterpolation(_:)` with their new behavior. See the
719
- /// `DefaultStringInterpolation` and `StringInterpolationProtocol` documentation
720
- /// for more details.
712
+ /// Extending the Default Interpolation Behavior
713
+ /// ============================================
721
714
///
722
- /// Creating a type which supports default string interpolation
723
- /// ===========================================================
715
+ /// Add new interpolation behavior to existing types by extending
716
+ /// `DefaultStringInterpolation`, the type that implements interpolation for
717
+ /// types like `String` and `Substring`, to add an overload of
718
+ /// `appendInterpolation(_:)` with their new behavior.
719
+ ///
720
+ /// For more information, see the `DefaultStringInterpolation` and
721
+ /// `StringInterpolationProtocol` documentation.
724
722
///
725
- /// Clients which want to create new types supporting string literals and
726
- /// interpolation, but which do not need any custom behavior, should conform
727
- /// their type to `ExpressibleByStringInterpolation` and implement an
728
- /// `init(stringLiteral: String)` method. Swift will automatically use
729
- /// `DefaultStringInterpolation` and provide an `init(stringInterpolation:)`
730
- /// implementation which passes the interpolated literal's contents to
731
- /// `init(stringLiteral:)`, so you won't need to implement anything special.
732
- ///
733
- /// Creating a type which supports custom string interpolation
734
- /// ==========================================================
723
+ /// Creating a Type That Supports the Default String Interpolation
724
+ /// ==============================================================
735
725
///
736
- /// If a conforming type wants to differentiate between literal and interpolated
737
- /// segments, restrict the types which can be interpolated into it, support
738
- /// different interpolators from the ones on `String`, or avoid constructing a
739
- /// `String` containing the data, it must specify a custom `StringInterpolation`
740
- /// associated type. This type must conform to `StringInterpolationProtocol` and
741
- /// must have a matching `StringLiteralType`.
742
- ///
743
- /// See the `StringLiteralProtocol` documentation for more details about how to
744
- /// do this.
726
+ /// To create a new type that supports string literals and interpolation, but
727
+ /// that doesn't need any custom behavior, conform the type to
728
+ /// `ExpressibleByStringInterpolation` and implement the
729
+ /// `init(stringLiteral: String)` initializer declared by the
730
+ /// `ExpressibleByStringLiteral` protocol. Swift will automatically use
731
+ /// `DefaultStringInterpolation` as the interpolation type and provide an
732
+ /// implementation for `init(stringInterpolation:)` that passes the
733
+ /// interpolated literal's contents to `init(stringLiteral:)`, so you don't
734
+ /// need to implement anything specific to this protocol.
735
+ ///
736
+ /// Creating a Type That Supports Custom String Interpolation
737
+ /// =========================================================
738
+ ///
739
+ /// If you want a conforming type to differentiate between literal and
740
+ /// interpolated segments, restrict the types that can be interpolated,
741
+ /// support different interpolators from the ones on `String`, or avoid
742
+ /// constructing a `String` containing the data, the type must specify a custom
743
+ /// `StringInterpolation` associated type. This type must conform to
744
+ /// `StringInterpolationProtocol` and have a matching `StringLiteralType`.
745
+ ///
746
+ /// For more information, see the `StringInterpolationProtocol` documentation.
745
747
public protocol ExpressibleByStringInterpolation
746
748
: ExpressibleByStringLiteral {
747
749
748
750
/// The type each segment of a string literal containing interpolations
749
- /// should be appended to. Its `StringLiteralType` should match the
750
- /// `StringLiteralType` of this type.
751
+ /// should be appended to.
752
+ ///
753
+ /// The `StringLiteralType` of an interpolation type must match the
754
+ /// `StringLiteralType` of the conforming type.
751
755
associatedtype StringInterpolation : StringInterpolationProtocol
752
756
= DefaultStringInterpolation
753
757
where StringInterpolation. StringLiteralType == StringLiteralType
@@ -770,7 +774,7 @@ extension ExpressibleByStringInterpolation
770
774
771
775
/// Creates a new instance from an interpolated string literal.
772
776
///
773
- /// Do not call this initializer directly. It is used by the compiler when
777
+ /// Don't call this initializer directly. It's used by the compiler when
774
778
/// you create a string using string interpolation. Instead, use string
775
779
/// interpolation to create a new string by including values, literals,
776
780
/// variables, or expressions enclosed in parentheses, prefixed by a
@@ -782,14 +786,13 @@ extension ExpressibleByStringInterpolation
782
786
/// If one cookie costs \(price) dollars, \
783
787
/// \(number) cookies cost \(price * number) dollars.
784
788
/// """
785
- /// print(message)
786
- /// // Prints "If one cookie costs 2 dollars, 3 cookies cost 6 dollars."
789
+ /// // message == "If one cookie costs 2 dollars, 3 cookies cost 6 dollars."
787
790
public init ( stringInterpolation: DefaultStringInterpolation ) {
788
791
self . init ( stringLiteral: stringInterpolation. make ( ) )
789
792
}
790
793
}
791
794
792
- /// Represents the contents of a string literal with interpolations while it is
795
+ /// Represents the contents of a string literal with interpolations while it's
793
796
/// being built up.
794
797
///
795
798
/// Each `ExpressibleByStringInterpolation` type has an associated
@@ -809,76 +812,94 @@ extension ExpressibleByStringInterpolation
809
812
/// The `StringInterpolation` type is responsible for collecting the segments
810
813
/// passed to its `appendLiteral(_:)` and `appendInterpolation` methods and
811
814
/// assembling them into a whole, converting as necessary. Once all of the
812
- /// segments have been appended, the interpolation will be passed to an
815
+ /// segments are appended, the interpolation is passed to an
813
816
/// `init(stringInterpolation:)` initializer on the type being created, which
814
817
/// must extract the accumulated data from the `StringInterpolation`.
815
818
///
816
- /// In simple cases, types conforming to `ExpressibleByStringInterpolation`
817
- /// can use `DefaultStringInterpolation` instead of writing their own. All they
818
- /// must do is conform to `ExpressibleByStringInterpolation` and implement
819
- /// `init(stringLiteral: String)`; interpolated string literals will then go
820
- /// through that initializer just as any other string literal would.
819
+ /// In simple cases, you can use `DefaultStringInterpolation` as the
820
+ /// interpolation type for types that conform to the
821
+ /// `ExpressibleByStringLiteral` protocol. To use the default interpolation,
822
+ /// conform a type to `ExpressibleByStringInterpolation` and implement
823
+ /// `init(stringLiteral: String)`. Values in interpolations are converted to
824
+ /// strings, and then passed to that initializer just like any other string
825
+ /// literal.
821
826
///
822
- /// The `appendInterpolation` Method
823
- /// ================================
824
- ///
825
- /// Each interpolated segment is translated into a call to a
826
- /// `StringInterpolationProtocol.appendInterpolation(...)` method, with the
827
- /// contents of the interpolation's parentheses treated as the call's argument
828
- /// list. That argument list can include multiple arguments and argument labels.
829
- /// For example:
830
- ///
831
- /// | If you write... | Swift calls... |
832
- /// |---------------- | --------------------------------- |
833
- /// | `\(x)` | `appendInterpolation(x)` |
834
- /// | `\(x, y)` | `appendInterpolation(x, y)` |
835
- /// | `\(foo: x)` | `appendInterpolation(foo: x)` |
836
- /// | `\(x, foo: y)` | `appendInterpolation(x, foo: y)` |
837
- ///
838
- /// `appendInterpolation` methods should return `Void` and should not be
839
- /// `static`. They otherwise support virtually all features of methods: they can
840
- /// have any number of parameters, can specify labels for any or all of them,
841
- /// can provide default values for parameters, can have variadic parameters, and
842
- /// can have parameters with generic types. Most importantly, they can be
843
- /// overloaded, so a `StringInterpolationProtocol`-conforming type can provide
844
- /// several different `appendInterpolation` methods with different behaviors.
845
- /// `appendInterpolation` methods can also throw; when a user uses one of these,
846
- /// they must mark the string literal with `try` or one of its variants.
827
+ /// Handling String Interpolations
828
+ /// ==============================
829
+ ///
830
+ /// With a custom interpolation type, each interpolated segment is translated
831
+ /// into a call to a special `appendInterpolation` method. The contents of
832
+ /// the interpolation's parentheses are treated as the call's argument list.
833
+ /// That argument list can include multiple arguments and argument labels.
834
+ ///
835
+ /// The following examples show how string interpolations are translated into
836
+ /// calls to `appendInterpolation`:
837
+ ///
838
+ /// - `\(x)` translates to `appendInterpolation(x)`
839
+ /// - `\(x, y)` translates to `appendInterpolation(x, y)`
840
+ /// - `\(foo: x)` translates to `appendInterpolation(foo: x)`
841
+ /// - `\(x, foo: y)` translates to `appendInterpolation(x, foo: y)`
842
+ ///
843
+ /// The `appendInterpolation` methods in your custom type must be mutating
844
+ /// instance methods that return `Void`. This code shows a custom interpolation
845
+ /// type's declaration of an `appendInterpolation` method that provides special
846
+ /// validation for user input:
847
+ ///
848
+ /// extension MyString.StringInterpolation {
849
+ /// mutating func appendInterpolation(validating input: String) {
850
+ /// // Perform validation of `input` and store for later use
851
+ /// }
852
+ /// }
853
+ ///
854
+ /// To use this interpolation method, create a string literal with an
855
+ /// interpolation using the `validating` parameter label.
856
+ ///
857
+ /// let userInput = readLine() ?? ""
858
+ /// let myString = "The user typed '\(validating: userInput)'." as MyString
859
+ ///
860
+ /// `appendInterpolation` methods support virtually all features of methods:
861
+ /// they can have any number of parameters, can specify labels for any or all
862
+ /// of their parameters, can provide default values, can have variadic
863
+ /// parameters, and can have parameters with generic types. Most importantly,
864
+ /// they can be overloaded, so a type that conforms to
865
+ /// `StringInterpolationProtocol` can provide several different
866
+ /// `appendInterpolation` methods with different behaviors. An
867
+ /// `appendInterpolation` method can also throw; when a user writes a literal
868
+ /// with one of these interpolations, they must mark the string literal with
869
+ /// `try` or one of its variants.
847
870
public protocol StringInterpolationProtocol {
848
871
/// The type that should be used for literal segments.
849
872
associatedtype StringLiteralType : _ExpressibleByBuiltinStringLiteral
850
873
851
874
/// Creates an empty instance ready to be filled with string literal content.
852
875
///
853
- /// Do not call this initializer directly. Instead, initialize a variable or
876
+ /// Don't call this initializer directly. Instead, initialize a variable or
854
877
/// constant using a string literal with interpolated expressions.
855
878
///
856
879
/// Swift passes this initializer a pair of arguments specifying the size of
857
880
/// the literal segments and the number of interpolated segments. Use this
858
- /// information to estimate the amount of storage you will need and
859
- /// pre-allocate it with a method like
860
- /// `RangeReplaceableCollection.reserveCapacity(_:)`.
881
+ /// information to estimate the amount of storage you will need.
861
882
///
862
883
/// - Parameter literalCapacity: The approximate size of all literal segments
863
884
/// combined. This is meant to be passed to `String.reserveCapacity(_:)`;
864
- /// it may be slightly larger or smaller than the sum of `String.count`
865
- /// called on each literal segment.
885
+ /// it may be slightly larger or smaller than the sum of the counts of each
886
+ /// literal segment.
866
887
/// - Parameter interpolationCount: The number of interpolations which will be
867
888
/// appended. Use this value to estimate how much additional capacity will
868
889
/// be needed for the interpolated segments.
869
890
init ( literalCapacity: Int , interpolationCount: Int )
870
891
871
892
/// Appends a literal segment to the interpolation.
872
893
///
873
- /// Do not call this method directly. Instead, initialize a variable or
894
+ /// Don't call this method directly. Instead, initialize a variable or
874
895
/// constant using a string literal with interpolated expressions.
875
896
///
876
- /// Interpolated expressions do not pass through this method; instead, Swift
877
- /// selects an overload of `appendInterpolation`. See the top-level
878
- /// `StringInterpolationProtocol` documentation for more details .
897
+ /// Interpolated expressions don't pass through this method; instead, Swift
898
+ /// selects an overload of `appendInterpolation`. For more information, see
899
+ /// the top-level `StringInterpolationProtocol` documentation.
879
900
///
880
901
/// - Parameter literal: A string literal containing the characters
881
- /// that appear next in the string literal.
902
+ /// that appear next in the string literal.
882
903
mutating func appendLiteral( _ literal: StringLiteralType )
883
904
884
905
// Informal requirement: Any desired appendInterpolation overloads, e.g.:
0 commit comments