Swift - Strings and Characters
Published: 2022-04-01 13:12:01

## String Literals
A string literal is a sequence of characters surrounded by double quotation marks (").

``` swift
example : 
let someString = "Some string literal value"
```

### Multiline String Literals
multiline string literal—a sequence of characters surrounded by three double quote.
example : 

``` swift
let quotation = """
The White Rabbit put on his spectacles.  "Where shall I begin,
please your Majesty?" he asked.
"Begin at the beginning," the King said gravely, "and go on
till you come to the end; then stop."
"""
``` 
**_If you want to use line breaks to make your source code easier to read, but you don’t want the line breaks to be part of the string’s value, write a backslash at the end of those lines_**

### Special Characters in String Literals
The escaped special characters 
\0 (null character), 
\\ (backslash), 
\t (horizontal tab), 
\n (line feed), 
\r (carriage return), 
\" (double quotation mark) and 
\' (single quotation mark)

### Extended String Delimiters
You can place a string literal within extended delimiters to include special characters in a string without invoking their effect. You place your string within quotation marks (") and surround that with number signs (#)

example :

``` swift
var string1 = #"Line 1\nLine 2"#   
var string2 = #"Line 1\#nLine 2"#
print(string1) // Line 1\nLine 2
print(string2) // Line 1
               // Line 2
```


**_Swift’s String type is a value type.
i.e. a new copy of value will be created everytime when it assigned to a new variable or constant or passed as a parameter to a function._**

---

## Character
A stand-alone Character constant or variable can be created  from a single-character string literal by providing a Character type annotation:

example : 

``` swift
let exclamationMark: Character = "!"
```

---

##String Interpolation
String interpolation is a way to construct a new String value from a mix of constants, variables, literals, and expressions

example : 

``` swift
let container = 3
let message = "container has \(container)"
// "container has 3"
```

- Different characters can require different amounts of memory to store, so in order to determine which Character is at a particular position, you must iterate over each Unicode scalar from the start or end of that String. For this reason, Swift strings can’t be indexed by integer values.


---

## String Property and Method

startIndex
endIndex 
index(before:) 
index(after:)  
index(_:offsetBy:) 

example : 

``` swift
let greeting = "Guten Tag!"
greeting[greeting.startIndex]  // G
greeting[greeting.index(before: greeting.endIndex)] // !
greeting[greeting.index(after: greeting.startIndex)] // u
let index = greeting.index(greeting.startIndex, offsetBy: 7)
greeting[index] // a
```

**_You can use the startIndex and endIndex properties and the index(before:), index(after:), and index(_:offsetBy:) methods on any type that conforms to the Collection protocol. This includes String, as shown here, as well as collection types such as Array, Dictionary, and Set.
_**

**insert(_:at:)** - To insert a single character into a string at a specified index,
**insert(contentsOf:at:)** - To insert the contents of another string at a specified index

example : 

``` swift
var welcome = "hello"
welcome.insert("!", at: welcome.endIndex)
// welcome now equals "hello!"
```

``` swift
welcome.insert(contentsOf: " there", at: welcome.index(before: welcome.endIndex)
// welcome now equals "hello there!"
```


**remove(at:)** - To remove a single character from a string at a specified index
**removeSubrange(_:)** - To remove a substring at a specified range.

example : 

``` swift
welcome.remove(at: welcome.index(before: welcome.endIndex))
// welcome now equals "hello there"
```

``` swift
let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex
welcome.removeSubrange(range)
// welcome now equals "hello"
```

**_You can use the insert(_:at:), insert(contentsOf:at:), remove(at:), and removeSubrange(_:) methods on any type that conforms to the RangeReplaceableCollection protocol. This includes String, as shown here, as well as collection types such as Array, Dictionary, and Set._**

---

## Substrings
substring from a string is an instance of **Substring** not another string.

The difference between strings and substrings is that, as a performance optimization, a substring can reuse part of the memory that’s used to store the original string, or part of the memory that’s used to store another substring.

**substrings aren’t suitable for long-term storage—because they reuse the storage of the original string, the entire original string must be kept in memory as long as any of its substrings are being used.**

convert the substring to an instance of String.

``` swift
let greeting = "Hello, world!"
let index = greeting.firstIndex(of: ",") ?? greeting.endIndex
let beginning = greeting[..<index]
// beginning is "Hello"
```

``` swift
// Convert the result to a String for long-term storage.
let newString = String(beginning)
```

**_Both String and Substring conform to the StringProtocol protocol, which means it’s often convenient for string-manipulation functions to accept a StringProtocol value. You can call such functions with either a String or Substring value._**

---

## Comparing Strings

- string and character equality (== and !=)
- prefix equality ( hasPrefix(_:) ) - compares string prefix
- suffix equality ( hasSuffix(_:) ) - compares string suffix