Swift 是一门静态的强类型语言。它以简单、干净、可读性好等特点著称。
1、 为什么是静态语言?
首先静态语言比之动态语言,更具有安全性。它不允许类型之间自动的进行转换,必须要显示的转换。Swift是类型安全的,它会在编译的时候就检查你的代码,任何类型不匹配时都会报错。这使得编程人员能够尽快捕获并尽可能早地在开发过程中修正错误。但是,这并不意味着你必须指定每一个常量和变量所声明的类型。如果不指定你需要的类型,Swift使用类型推导来指定出相应的类型。类型推导使编译器在编译的时候通过你提供的初始化值自动推导出特定的表达式的类型。类型推导使Swift比起C或Objective-C只需要更少的类型声明语句。常量和变量仍然显式类型,但大部分指定其类型的工作Swift已经为你完成了。当你声明一个常量或变量并给出初始值类型的时候,类型推导就显得特别有用。这通常是通过给所声明的常量或变量赋常值来完成的。
例如:你要声明一个用户名字符串常量,并为他赋值叫“json”.
let userName = "son"
不必指定什么类型,在编译时会通过类型推导的机制将常量userName 自动设为 赋的值的类型。
2、什么叫强类型语言?
即变量或者常量,必须要先定义然后才能使用,否则会报错。
好了 ,言归正传,下面给大家介绍下Swift 中的字符串和集合
字符与字符串
Swift集百家之长,吸收了主流语言Java、C、C++等的好的特性,所以它功能十分强大,今天我们就来看看它强大的字符串。
首先,我们带着这样几个问题去了解、理解swift的字符串。
1、swift字符串怎么初始化的?
2、swift字符串长度可变吗?
3、swift字符串是指针,还是实际的值?
4、swift有哪些特性?
下面,我来一一解答这些问题。
(1) swift 字符串的初始化有2种方式,这两种方式的结果都是一样的。我们来初始化一个空字符串。
var str1 = "" // 第一种方式
var str2 = String() // 第二种方式
var str3 = "hello word" // 当初始化一个非空字符串时,可以这样
(2) swift字符串长度是可变的,当然这只针对于用var 定义的字符串,用let定义的字符串常量是不可变的。正因为这个特性,它可以和其他字符,字符串通过符号“ = ”、“ += ”组合成新的字符串。
var str1 = "hello"
var str2 = "world"
var str3:Character = "!" // 这是定义字符的方式
var strs1 = str1 + str2 // 结果为“hello word”
(3)swift字符串 是实际的值,不是指针。当把字符串变量赋值给另一个值,它原来的值不变。当把字符串变量当作参数传递时,它也是一个实际的值。
var str1 = "你好"
var str2 = str1 // 这时,str1的值还是“你好”
由此可见,它不是指针,是一个实际的值。
(4)swift字符串有哪些特性?它的比较机制,验证机制,遍历机制,转换机制,组合机制,都是它的特性。
a、比较机制。字符串之间的比较是可以分多样的。
它比较完全相等时,用“==”来连接;
它比较前缀相等时,给定一个字符串前缀,然后用要比的字符串,调用hasPrefix方法,参数为给定的前缀;
它比较后缀相等时,给定一个字符串后缀,然后用要比的字符串,调用hasSuffix方法,参数为给定的后缀。
举个例子,我们学校在开兴趣班,要统计各个兴趣班的人数有多少?用这个就可以很容易的找出来。
let students = [
"iOS,谢明,s3sj101",
"android,胡军,s3jn95",
"iOS,都美君,s3jn95",
"技术支持,高小龙,s3jn92",
"数据库,阿斯,s3jn92",
"数据库,封剑,s3j101"
]
var ios = 0 // 定义ios班的人数
var android = 0 // 定义android班的人数
var technical = 0 // 定义技术支持班的人数
var database = 0 // 定义数据库班的人数
for student in students {
if student.hasPrefix("iOS") {
ios++
}
if student.hasPrefix("android") {
android++
}
if student.hasPrefix("技术支持") {
technical++
}
if student.hasPrefix("数据库") {
database++
}
}
print("报iOS班的人数:\(ios)") // 2
print("报android班的人数:\(android)") // 1
print("技术支持班的人数:\(technical)") // 1
print("数据库班的人数:\(database)") // 2
如果我们要统计各个原班有多少人,可以这样做:
let students = [
"ios,谢明,s3sj101",
"android,胡军,s3jn95",
"ios,都美君,s3jn95",
"技术支持,高小龙,s3jn92",
"数据库,阿斯,s3jn92",
"数据库,封剑,s3j101"]
var s3jn95 = 0 // 定义s3jn95班的人数
var s3jn92 = 0 // 定义s3jn92班的人数
var s3j101 = 0 // 定义s3j101班的人数
for student in students {
if student.hasSuffix("s3jn95") {
s3jn95++
}
if student.hasSuffix("s3jn92") {
s3jn92++
}
if student.hasSuffix("s3j101") {
s3j101++
}
}
print("s3sj95班的人数:\(s3jn95)") // 2
print("s3jn92班的人数:\(s3jn92)") // 2
print("s3j101班的人数:\(s3j101)") // 1
b:验证机制。判断一个字符串是不是为空,我们可以用isEmpty属性获取
var str = ""
if str.isEmpty {
print("str是空字符串") // 执行结果:str是空字符串
}
else {
print("str是非空字符串")
}
c:遍历机制。我们知道,字符串是有字符组成,swift可以遍历字符串中的每个字符。
var str = "HelloWorld"
for i in str.characters {
print(i)
}
执行结果会把每个字符遍历出来。
d:转换机制。它还支持字符串的大小写转换。通过uppercaseString和lowercaseString属性可以做到,我们来看看:
var str = "helloWorld"
var upper = ""
var lower = ""
upper = str.uppercaseString // 定义一个存放转化为大写后的变量
lower = str.lowercaseString // 定义一个存放转化为小写后的变量
print(upper)
print(lower)
然后分别输出就行了 ,很简单吧。。。
e:组合机制.组合机制是它很大的一个亮点,它的长度是可变的,因此也是可以组合的。这给我们的开发带来很大的遍历,是我们开发者的福音哦。
这里就不举例了,他们之间可以通过“+”、“+=”、也可以通过一个合法的表达式生成新的字符串。最后,它还可以计算字符串的总长度,
需要用到的方法是:countElements。参数为要计算的字符串本身。
获取字符串的长度
var str = "helloWorld"
// 获取字符集合,再获取集合的count属性
let count = str.characters.count // 10
两个字符串的拼接
let str1 = "Hello"
let str2 = "World"
let str3 = str1 + str2 //HelloWorld
字符串和其他数据类型的拼接
let name = "why"
let age = 18
let info = "my name is \(name),age is \(age)" // my name is why,age is 18
字符串的格式化
// 比如时间: 03:04
let min = 3
let second = 4
let time = String(format: "%02d:%02d", arguments:[min,second]) // "03:04"
字符串的截取
// 1.简单的方式是将String转成NSString来使用,在标识符后加 as NSString即可
let myStr = "HelloWorld"
var subStr = (myStr as NSString).substringFromIndex(5) // return "World"
subStr = (myStr as NSString).substringToIndex(5) // return "Hello"
subStr = (myStr as NSString).substringWithRange(NSRange(location: 5, length: 5)) // return "World"
// 2.Swift截取方式
let str = "MyPlayground"
// 截取开始位置
let fromindex = str.startIndex.advancedBy(2)
let header = str.substringToIndex(fromindex) // retrun "My"
// 截取结束位置
let toindex = str.endIndex.advancedBy(-6)
let footer = str.substringToIndex(toindex) // return "MyPlay"
// 截取中间的字符串
let range = Range(start: str.startIndex.advancedBy(2), end: str.endIndex.advancedBy(-6))
let middle = str.substringWithRange(range) // return "Play"
数组
Swift提供了3种主要的集合类型,array,set,dictionary。本节介绍array。
数组是存储有序的相同类型的集合,相同的值可以多次出现在不同的位置。
注意:
Swift的Array类型桥接Foundation的NSArray类
数组类型简单语法
Swift数组类型完整写作Array<Element>,Element是数组允许存储值的合法类型,你也可以简单的写作[Element]。尽管两种形式在功能上是一样的, 但是我们推荐较短的那种,而且在本文中都会使用这种形式来使用数组。
创建数组
// 创建一个空数组
var someInts = [Int]()
print("someInts is type [Int] with \(someInts.count) items.") // return:0
需要注意的是,someInts变量的类型在初始化时推断为一个int类型,或者如果上下文已经提供类型信息,例如一个函数参数或者一个已经定义好类型的常量或者变量,我们也可以直接写作 [],而不需要加Int。
someInts.append(3) // someInts now contains 1 value of type Int
someInts = [] // someInts is now an empty array, but is still of type [Int]
创建一个带有默认值的数组
Swift 中的Array类型还提供了一个可以创建特定大小并且所有数据设置为相同的默认值的构造方法。我们可以把准备加入数组的item数量(count)和适当类型的初始值(repeatedValue)传入数组构造函数:
// 创建一个带有默认值的数组
// threeDoubles is of type [Double], and equals [0.0, 0.0, 0.0]
var threeDoubles = [Double](count: 3, repeatedValue: 0.0)
2个数组合并为一个数组
通过+来实现2个数组合为一个新数组
// 2个数组合并为一个数组
// 通过+来实现2个数组合为一个新数组
//anotherThreeDoubles is of type [Double], and equals [2.5, 2.5, 2.5]
var anotherThreeDoubles = [Double](count: 3, repeatedValue: 2.5)
// sixDoubles is inferred as [Double], and equals [0.0, 0.0, 0.0, 2.5, 2.5, 2.5]
var sixDoubles = threeDoubles + anotherThreeDoubles
var shoppingList:[String] = ["Eggs","Milk"]
// 这里说明shoppingList是一个存储String类型的数组变量,而且只能存储String类型的值。它还可以简单的写作
var shoppingList2 = ["Eggs","Milk"]
数组的访问和修改
// 获取数组数据 - 下标法
// firstItem is equal to "Eggs
var firstItem = shoppingList[0]
// 添加数据 - 使用append(_:)方法在数组的结尾处添加一条新的数据。
shoppingList.append("Flour")
// 使用+=也可以向数组中添加若干条新的数据
// shoppingList now contains 4 items
shoppingList += ["Baking Powder"]
// shoppingList now contains 7 items
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
// 使用insert(_:atIndex:)在指定位置插入新的数据
// shoppingList now contains 7 items
// "Maple Syrup" is now the first item in the list
shoppingList.insert("Maple Syrup", atIndex: 0)
// 修改数组 - 下标法修改其中一项值
shoppingList[0] = "Six eggs"
// 也可以修改指定范围内的值
// shoppingList now contains 6 items
shoppingList[4...6] = ["Bananas", "Apples"]
// removeAtIndex(_:)删除数组中指定位置的数据
// the item that was at index 0 has just been removed
// shoppingList now contains 6 items, and no Maple Syrup
// the mapleSyrup constant is now equal to the removed "Maple Syrup" string”
let mapleSyrup = shoppingList.removeAtIndex(0)
shoppingList
我们可以通过数组的方法和属性来访问和修改数组,或者下标语法。 使用数组的只读属性count来获取数组的count。
使用isEmpty判断数组是否为空。
我们不可以通过下标法来在数组的末尾处添加新的数据,因为index超出数组长度后是不合法的,会发生运行时错误
如果你像删除数组中最后一条数据,那么你应该使用removeLast(),而不应该使用removeAtIndex(),因为它不用查询数组的长度。
数组的遍历
你可以使用for-in'循环来遍历数组
// 你可以使用for-in'循环来遍历数组
for item in shoppingList {
print(item)
}
如果我们同时需要每个数据项的值和索引值,可以使用全局enumerate函数来进行数组遍历。enumerate返回一个由每一个数据项索引值和数据值组成的键值对组。我们可以把这个键值对组分解成临时常量或者变量来进行遍历:
for (index,value) in shoppingList.enumerate() {
print("Item \(index+1):\(value)")
}
// Item 1: Six eggs
// Item 2: Milk
// Item 3: Flour
// Item 4: Baking Powder
// Item 5: Bananas”
字典
字典是一种存储相同类型多重数据的存储器。每个值(value)都关联独特的键(key),键作为字典中的这个值数据的标识符。和数组中的数据项不同,字典中的数据项并没有具体顺序。
字典写作Dictionary<Key, Value>。也可以写作[Key: Value]
// 创建空字典
// namesOfIntegers is an empty [Int: String] dictionary
var namesOfIntegers = [Int:String]()
// namesOfIntegers now contains 1 key-value pair
namesOfIntegers[16] = "sixteen"
namesOfIntegers
// namesOfIntegers is once again an empty dictionary of type [Int: String]
namesOfIntegers = [:]
namesOfIntegers
// 创建字典
var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
airports
// 类型推断
var airports2 = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
airports2
airports["LHR"] = "London Heathrow"
airports
// 访问和修改
// Prints "The old value for DUB was Dublin.
if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") {
print("The old value for DUB was \(oldValue).")
}
airports
// removeValueForKey(_:)删除键值对
if let removedValue = airports.removeValueForKey("DUB") {
print("The removed airport's name is \(removedValue).")
} else {
print("The airports dictionary does not contain a value for DUB.")
}
airports
// 遍历
for (airportCode, airportName) in airports {
print("\(airportCode): \(airportName)")
}
// YYZ: Toronto Pearson
// LHR: London Heathrow
for airportCode in airports.keys {
print("Airport code: \(airportCode)")
}
// Airport code: YYZ
// Airport code: LHR
for airportName in airports.values {
print("Airport name: \(airportName)")
}
// Airport name: Toronto Pearson
// Airport name: London Heathrow
// count返回字典的键值对数
// isEmpty判断字典是否为空
Sets
Sets是存储无序的相同类型的值,你可以在顺序不重要的情况下使用Sets来替代数组,或者当你需要同一个值在集合中只出现一次时。
Sets类型语法
写作Set<Element>,Element是sets允许存储的类型
// 创建并初始化一个空的set
var letters = Set<Character>()
print("letters is of type Set<Character> with \(letters.count) items.")
// Prints "letters is of type Set<Character> with 0 items.
// 如果可以推断出它元素的类型也可以写作
letters = []
// 通过数组字面量来创建set
var favoriteGenres:Set<String> = ["Rock", "Classical", "Hip hop"]
// favoriteGenres has been initialized with three initial items
// 或者(因为可以推断为set<String>)
var favoriteGenres2:Set = ["Rock", "Classical", "Hip hop"]
// favoriteGenres2 has been initialized with three initial items
// 访问和修改
// count方法返回set的数据项数目
print("I have \(favoriteGenres.count) favorite music genres.")
// Prints "I have 3 favorite music genres.
// isEmpty判断set是否为空
// contains(_:)检查set对象是否包含特定的数据。
if favoriteGenres.contains("Funk") {
print("I get up on the good foot.")
} else {
print("It's too funky in here.")
}
// Prints "It's too funky in here.
// 添加新数据项
// insert(_:)向现有的set对象添加新的数据
favoriteGenres.insert("Jazz")
// favoriteGenres now contains 4 items
// 删除已有的数据项
// remove(_:)向现有的set对象删除已有的数据
if let removedGenre = favoriteGenres.remove("Rock") {
print("\(removedGenre)? I'm over it.")
} else {
print("I never much cared for that.")
}
// Prints "Rock? I'm over it.
// 遍历set
// 使用for in语句遍历set
for genre in favoriteGenres {
print("\(genre)")
}
// Classical
// Jazz
// Hip hop
// set无序存储数据,使用sort()可以按到升序排序。
// intersect(_:)创意一个包含两set对象共有的数据的新的Set对象
// exclusiveOr(_:)创意一个不包含两set对象共有的数据的新的Set对象
// union(_:)创意一个包含两set对象所有的数据的新的Set对象
// subtract(_:)创意一个只存在其中一个已有的set类型数据的新的Set对象
let oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]
oddDigits.union(evenDigits).sort()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
oddDigits.intersect(evenDigits).sort()
// []
oddDigits.subtract(singleDigitPrimeNumbers).sort()
// [1, 9]
oddDigits.exclusiveOr(singleDigitPrimeNumbers).sort()
// [1, 2, 9]
// ==操作符比较2个set的值是否全部相同
let houseAnimals: Set = ["🐶", "🐱"]
let farmAnimals: Set = ["🐮", "🐔", "🐑", "🐶", "🐱"]
let cityAnimals: Set = ["🐦", "🐭"]
houseAnimals.isSubsetOf(farmAnimals) // true
farmAnimals.isSupersetOf(houseAnimals) // true
farmAnimals.isDisjointWith(cityAnimals) // true