swift學習筆記6
字元和字元串
在swift中,String類型也是結構體,屬于值類型,而不是引用類型。這一點,與OC是不一樣的。
//
// main.swift
// swift06
//
// Created by iOS on 2018/9/25.
// Copyright © 2018年 weiman. All rights reserved.
//
import Foundation
// 概述
do {
let a = "a"
print(a)
let b = "hello"
print(b)
let c = "你好呀"
print(c)
let d = """
今天天氣很好,我出去逛逛。
it is a good day today, I'm going to have a walk.
今日は天気がよいので,私は出かけて出かけます.
"""
print(d)
}
//注意,swift中引入了多行字元串字面量的表達形式,通過 """三個雙引号包圍起來,可以輸入換行符。
// 輸出不想有換行符,但是文字較長,在書寫的時候有換行符,這個時候我們可以在換行符前面加上 \,例如:
do {
let a = """
白日依山盡,\
黃河入海流。\
欲窮千裡目,\
更上一層樓
"""
print(a)
/*
輸出: 白日依山盡, 黃河入海流。 欲窮千裡目, 更上一層樓
*/
}
// 字元
/*
在swift程式設計語言中,對字元的表示是獨立于某一種特定的Unicode編碼的。
整個Unicode标準編碼由三個平面構成:
1.基本多語言平面:大部分拉丁字母、希臘字母、标點符号、亞洲的部分字母;
2.補充平面:包含了某些不在基本多語言平面的非拉丁字元、亞洲文字等,所有Emoji表情;
3.保留平面:永久保留的碼點部分。
*/
do {
// 建立一個字元對象 ‘0’
// 注意,使用UnicodeScalar構造出來的對象是可選的。
let zero = UnicodeScalar("0")
if let z = zero {
print("z = \(z)")
print("scalar value = \(z.value)")
}
// 使用類型标注的方式聲明并初始化a
let a: UnicodeScalar = "a"
print("a = \(a)")
print("scalar value = \(a.value)")
let pai = UnicodeScalar("π")
if let p = pai {
print("pai = \(p)")
print("scalar value = \(p.value)")
}
let 好: UnicodeScalar = "好"
print("好 = \(好)")
}
/*
UnicodeScalar可以表示字元,那麼為什麼還需要Character呢?
因為現在充斥着各種豐富的Emoji表情,光20位的碼點已經無法滿足需求了,需要Emoji已經用兩個
碼點進行表示了,比如各國的國旗。是以,swift中使用Character類型以覆寫所有的可被編碼的字元。
也就是說,一個Characteru對象可包含多個UnicodeScalar對象。
*/
//let flag: UnicodeScalar = "🇺🇸"
//報錯 Cannot convert value of type 'String' to specified type 'UnicodeScalar' (aka 'Unicode.Scalar')
let flag: Character = "🇺🇸"
print("flag: \(flag)")
// 通過碼點來構造UnicodeScalar類型的對象。
let c = UnicodeScalar(127464)!
let n = UnicodeScalar(127475)!
print("c = \(c), n = \(n)")
//我們将兩個UnicodeScalar對子昂的字元對象拼在一起,構成一個String對象,然後用Character
//構造方法将這個String對象中的内容轉換為Character相應的值。
let cn = Character(String([Character(c),Character(n)]))
print("cn = \(cn)")
// 2. 轉義字元
print("\n")
print("---------轉義字元-------------")
/*
什麼是轉義字元?
轉義字元用來表示這些無法在源代碼中表示的特殊字元。
如何表示?
swift中使用反斜杠作為轉義字元的引導字首。
*/
do {
let s = "Say, \"Hello\",很好!"
print(s)
let a = "🇺🇸".unicodeScalars.first?.value
let b = "🇺🇸".unicodeScalars.last?.value
print("a = \(a), b = \(b)")
}
//3. 字元串(String)
do {
// 空字元串
let a = ""
print(a)
let b = String()
print(b)
let c = "hello"
print(c)
let d = "你好"
print(d)
// 常用屬性
//1. 拼接字元串
let e = c + d
print("e = \(e)")
//2. +=拼接
var f = "aaa"
f += "bbb"
print("f = \(f)")
//3. == 比較
if a == b {
print("字元串相等")
} else {
print("不相等")
}
//4. 判斷是否為空字元串
if a.isEmpty {
print("a是空字元串")
} else {
print("非空字元串")
}
//5. 包含子串
if f.contains("a") {
print("包含子串")
} else {
print("不包含子串")
}
//6.是否以某字元串開頭
if f.hasPrefix("a") {
print("以a開頭")
} else {
print("不是以a開頭")
}
//7. 是否以某字元串結尾
if f.hasSuffix(".mp4") {
print("結尾包含.mp4")
} else {
print("結尾不包含.mp4")
}
}
// 4. 字元串插值
什麼是字元串插值?
swift語言提供了一種十分便利的方式可以将幾乎任一類型的對象轉換為一個字元串的表示形式,
這就叫做字元串插值。
其實,我們在之前的列印中已經多次用到了字元串插值,隻是沒有提出這一概念。
文法:(Obj)
do {
let x = 10, y = 20
let s = "x + y = \(x + y)"
print("s is \(s)")
// 或
print("s is:" + s)
// 自定義類型
struct MyType {
var x = 10, y = 20
}
let str = "my type: \(MyType())"
print("自定義類型: \(str)")
// 自定義類型定制字元串表達描述
struct MyStruct: CustomStringConvertible {
var a = 10
var b = 20
var description: String {
return String("MyStruct: a = \(a), b = \(b)")
}
}
var obj = MyStruct()
obj.a = -obj.a
obj.b *= 2
print("哈哈哈,自定義: \(obj)")
}
// 5.字元串的characters屬性
如果我們想要疊代通路一個字元串的每個字元,或者是查詢目前字元串中包含了多少字元個數,那麼我們可以通路
String對象的characters屬性。
注意:characters屬性是swift3.2以下的屬性,之後就不建議使用了。
我們在這裡簡單了解以下。
@available(swift, deprecated: 3.2, message: "Please use String or Substring directly")
public var characters: String.CharacterView
do {
var str = "看看旗幟1:\u{1f1e8}"
print("count: \(str.count)")
print("before appending :", separator: "",terminator: "")
// 輸出字元序列
for ch in str.characters {
print("\(ch)", separator: "", terminator: " ")
}
print("\n")
//新增一個字元
str.append("\u{1f1f3}")
//輸出目前字元串中字元個數
print("count: \(str.count)")
for ch in str {
print("\(ch)", separator: "", terminator: " ")
}
let str2 = "看看旗幟2:\u{1f1e8}\u{1f1f3}"
print("count: \(str2.count)")
print(str2)
// 字元串的最後和第一個字元屬性
print("第一個字元: \(str2.first ?? " " )")
print("最後一個字元: \(str2.last ?? " " )")
// 注意:first和last屬性都是傳回的可選類型
}
// 6. 字元串的索引以及字元通路
注意:我們不能通過下标索引的方式通路字元串中的指定位置的字元,那麼我們該如何通路單獨的字元呢?
swift程式設計語言為string類型引入了索引類型String.Index用于表示字元串對象中字元序列的索引值。
由于String.Index類型遵循了Comparable協定,是以它可以作為範圍操作符的操作數。
swift中String.Index的聲明如下:
/// A position of a character or code unit in a string.
public struct Index {
}
do {
// 常用屬性
//1.開始位置,結束位置
var str = "00000000000000000000"
let start = str.startIndex
let end = str.endIndex
//2.獲得指定的索引值
// index( _ , offsetBy: _)
// 第一個參數:開始位置
// 第二個參數:偏移量,為正數:傳回的索引值往後挪n位,為負數:往前挪n位。
let index = str.index(start, offsetBy: 5)
str.insert("1", at: index)
print("newstr: \(str)")
// newstr: 000001000000000000000
/*
index(_, offsetBy: _, limitedBy: _)
作用與 index( _ , offsetBy: _) 一樣。
第一個參數:開始位置
第二個參數:偏移量
第三個參數:邊界檢測,如果索引計算的結果超過了邊界,此方法就會傳回空,是以傳回值是一個可選值。
*/
if let index2 = str.index(end, offsetBy: -5, limitedBy: start) {
str.insert("2", at: index2)
print("str2: \(str)")
//str2: 0000010000000002000000
}
//3.Substring類型
/*
public struct Substring : StringProtocol {
....
}
Substring類型的對象是一個優化過的子串對象模型,它不僅具有String幾乎全部的屬性和方法
,而且它共享了其原始字元串的存儲空間,使得對它的操作非常快捷。
*/
let myString = "好好學習,天天向上,每天都是好天氣。🇨🇳"
let startIndex = myString.startIndex
let endIndex = myString.endIndex
let index3 = myString.index(startIndex, offsetBy: 3)
let index10 = myString.index(startIndex, offsetBy: 10, limitedBy: endIndex)
if let temp = index10 {
let subStr = myString[index3 ..< temp]
var ch = subStr.first
print("first = \(ch ?? " " )")
ch = subStr.last
print("last: \(ch ?? " " )")
}
/*
注意:
endIndex屬性指定的是字元串中最後一個字元的後一個索引位置,是以該屬性的前一個位置才是此字元串
中的最後一個字元的位置,這一點一定要注意。
*/
}