startindex 不能大于字符串长度_swift-3.字符串

3.1 概览

字符串是一系列字符的集合。

1.可以通过字符串字面量和字符串插值创建字符串

//  字符串字面量 是 用双引号括起来的字符集合
//  用字符串字面量"Welcome!" 定义字符串变量greeting
let greeting = "Welcome!"

//  字符串插值
let name = "Rosa"
let personalizedGreeting = "Welcome, (name)!"
// personalizedGreeting == "Welcome, Rosa!"

let price = 2
let number = 3
let cookiePrice = "(number) cookies: $(price * number)."
// cookiePrice == "3 cookies: $6."

2.可以用 + 号连接字符串

let longerGreeting = greeting + " We're glad you're here!"
// longerGreeting == "Welcome! We're glad you're here!"

3.多行字符串用3个双引号标记

//  Multi-line string literal content must begin on a new line
//  Multi-line string literal closing delimiter must begin on a new line
//  Insufficient indentation of line in multi-line string literal base on closing delimiter
let banner = """
          __,
         (           o  /) _/_
          `.  , , , ,  //  /
        (___)(_(_/_(_ //_ (__
                     /)
                    (/
        """
print(banner)

3.2 修改和比较字符串

修改字符串

var otherGreeting = greeting
otherGreeting += " Have a nice time!"
// otherGreeting == "Welcome! Have a nice time!"
print(greeting)
// Prints "Welcome!"

swfit字符串比较是比较的是unicode标准表示,和本地设置无关。可以通过==、和关系运算符 (><=等)比较

//  unicode 标量 `"u{301}"` 改变可前一个字符的声调
//  `"eu{301}"` 和 "é"` 有相同的unicode标准表示
let cafe1 = "Cafeu{301}"
let cafe2 = "Café"
print(cafe1 == cafe2)
// Prints "true"

3.3 访问字符串的元素

3.3.1 字符串索引

每一个 String 值都有一个关联的索引(index)类型,String.Index,它对应着字符串中的每一个 Character 的位置。不同的字符可能会占用不同数量的内存空间,所以要知道 Character 的确定位置,就必须从 String 开头遍历每一个 Unicode 标量直到结尾。因此,Swift 的字符串不能用整数(integer)做索引。

//  startIndex 非空字符串的第一个字符的位置。
//  @inlinable public var startIndex: String.Index { get }
//  endIndex 非空字符串的最后一个字符的后一个位置索引。
//  @inlinable public var endIndex: String.Index { get }
//  一个空字符串的 startIndex 和 endIndex 相等

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

//试图获取越界索引对应的 Character,将引发一个运行时错误。
//greeting[greeting.endIndex] // error
//greeting.index(after: greeting.endIndex) // error
//使用 indices 属性会创建一个包含全部索引的Range(Range是一个包含连续值得集合),用来在一个字符串中访问单个字符。
for index in greeting.indices {
   print("(index) => (greeting[index]) ")
}
//  Index(_rawBits: 1) => G
//  Index(_rawBits: 65793) => u
//  Index(_rawBits: 131329) => t
//  Index(_rawBits: 196865) => e
//  Index(_rawBits: 262401) => n
//  Index(_rawBits: 327937) =>
//  Index(_rawBits: 393473) => T
//  Index(_rawBits: 459009) => a
//  Index(_rawBits: 524545) => g
//  Index(_rawBits: 590081) => !

3.3.2 插入和删除字符串

var welcome = "hello"
welcome.insert("!", at: welcome.endIndex)
// welcome 变量现在等于 "hello!"

welcome.insert(contentsOf:" there", at: welcome.index(before: welcome.endIndex))
// welcome 变量现在等于 "hello there!"

welcome.remove(at: welcome.index(before: welcome.endIndex))
// welcome 现在等于 "hello there"

let range = welcome.index(welcome.endIndex, offsetBy: -6)..

3.3.3 子字符串

let greeting = "Hello, world!"
let index = greeting.firstIndex(of: ",") ?? greeting.endIndex
let beginning = greeting[..

Substring 可以重用原 String 的内存空间,或者另一个 Substring 的内存空间(String 也有同样的优化,但如果两个 String 共享内存的话,它们就会相等)。这一优化意味着你在修改 String 和 Substring 之前都不需要消耗性能去复制内存。就像前面说的那样,Substring 不适合长期存储 —— 因为它重用了原 String 的内存空间,原 String 的内存空间必须保留直到它的 Substring 不再被使用为止。 上面的例子,greeting 是一个 String,意味着它在内存里有一片空间保存字符集。而由于 beginning 是 greeting 的 Substring,它重用了 greeting 的内存空间。相反,newString 是一个 String —— 它是使用 Substring 创建的,拥有一片自己的内存空间。下面的图展示了他们之间的关系:

startindex 不能大于字符串长度_swift-3.字符串_第1张图片

你可能感兴趣的:(startindex,不能大于字符串长度)