02 Swift元組/!與?簡單介紹/字符串

1.元組

1.1什么是元組

在其他語言中很早就有元組這個概念, 但是對于OC程序員來說這是一個新的概念
官方定義:元組(tuples)把多個值組合成一個復合值.
元組內(nèi)的值可以是任意類型, 并不需要是相同的類型.
自定義(我定義):將多個相同對或者不同類型的值用一個小括號起來就是一個元組.

1.2定義元組(代碼):

let student = ("jianshu", 30, 22.2)
print(student)
print(student.0)
print(student.1)
print(student.2)

其實元組定義其實和結(jié)構(gòu)體很像, 只是不需要提前定義類型.
元組其實是復合類型, 小括號中可以寫任何類型
也可以指定數(shù)據(jù)類型
如果指定餓了數(shù)據(jù)類型, 那么對應的必須是其他定的數(shù)據(jù)類型, 否則會報錯.

let student: (String, Int, Double) = ("jianshu", 30, 22.2)

1.3定義元組其他方式

指定元組元素的名稱

let student = (name:"jianshu", age = 30, score: 43)
print(student.name)
print(student.age)
print(student.score)

通過指定的名稱提取元組對應的值, 會將對應的值賦值給對應位置的名稱

let (name, age, score) = ("jianshu", 30, 43)
print(name)
print(age)
print(score)

如果不關心元組中的某一個值可以利用_通配符來忽略提取

let student = ("jianshu", 30, 43)
let (name, age, _) = student
print(name)
print(age)

1.4外話

在以前沒有元組之前C和OC是通過傳入指針或者返回結(jié)構(gòu)體的方式來返回多個值的, 而有了元組之后就可以實現(xiàn)讓一個函數(shù)返回多個值

2 Swift可選值

**使用可選類型(optionals)來處理值可能缺失的情況. **
C和Objective-C中沒有可選類型這個概念
最接近的是OC中的一個特性,
一個方法要么返回一個對象, 要么返回nil, nil表示"缺少一個合法的對象"
可選值:optionals有兩種狀態(tài)

1.有值
2.沒有值

?表示兩種狀態(tài), 一種是有值(有具體的某個值), 一種是沒有值(沒有代表nil), 當?修飾時,表示這個變量可能為nil

// 有值
var optValue: Int? = 9
// 沒有值
var optValue: Int?
var optValue: Int? = nil

2.1可選值可以利用if語句來進行判斷

var optValue: Int? = 10
if optValue != nil
{
    print("有值:\(optValue)")
}else
{
    print("沒有值:\(optValue)")
}

輸出結(jié)果: 有值: Optionals(10)

var optValue: Int?
var optValue: Int? = nil
if optValue != nil
{
    print("有值:\(optValue)")
}else
{
    print("沒有值:\(optValue)")
}

輸出結(jié)果:沒有值:nil

var optValue: Int? = nil
if optValue != nil
{
    print("有值:\(optValue)")
}else
{
    print("沒有值:\(optValue)")
}

輸出結(jié)果:沒有值:nil

2.2提取可選類型的值(使用!強制解析)

將optValue中的整型值強制拿出來賦值給變量result, 換句話說就是告訴編譯器optValue一定有值
因為可選類型有兩種狀態(tài)有值和沒有值, 所以需要告訴編譯器到底有沒有值
需要注意的是如果強制解析optValue
但是optValue中沒有值時會引發(fā)一個運行時錯誤

var optValue: Int? = 9
var result: Int = optValue!
print(result)

輸出結(jié)果:9

var optValue: Int?
var result: Int = optValue!
print(result)

結(jié)果為報錯:
fatal error:
unexpectedly found nil while unwrapping an Optional value

2.3可選綁定

為了更安全的解析可選類型的值, 一般情況下使用可選綁定
如果optValue沒有值就不會做任何操作
如果optValue有值會返回true并將optValue的值賦值給result執(zhí)行大括號中的內(nèi)容

var optValue: Int? = 9
if let result = optValue
{
    print(result)
}

2.4!與?詳解

解釋一:


Optional其實是個enum攀细,里面有None和Some兩種類型。其實所謂的nil就是Optional.None, 非nil就是Optional.Some, 然后會通過Some(T)包裝(wrap)原始值,這也是為什么在使用Optional的時候要拆包(從enum里取出來原始值)的原因, 也是PlayGround會把Optional值顯示為類似{Some "hello world"}的原因,這里是enum Optional的定義:

enum Optional<T> : LogicValue, Reflectable {
case None
case Some(T)
init()
init(_ some: T)

/// Allow use in a Boolean context.
func getLogicValue() -> Bool

/// Haskell's fmap, which was mis-named
func map<U>(f: (T) -> U) -> U?
func getMirror() -> Mirror

}
聲明為Optional只需要在類型后面緊跟一個?即可哥力。如:

var strValue: String?   //?相當于下面這種寫法的語法糖
var strValue: Optional<String>

上面這個Optional的聲明未巫,意思不是”我聲明了一個Optional的String值”, 而是”我聲明了一個Optional類型值,它可能包含一個String值筋栋,也可能什么都不包含”,也就是說實際上我們聲明的是Optional類型正驻,而不是聲明了一個String類型弊攘,這一點需要銘記在心仔涩。
建議再讀一遍上段文字扑浸。
一旦聲明為Optional的,如果不顯式的賦值就會有個默認值nil择浊。判斷一個Optional的值是否有值伤靠,可以用if來判斷:

if strValue {
    //do sth with strValue
}

然后怎么使用Optional值呢捣域?文檔中也有提到說,在使用Optional值的時候需要在具體的操作宴合,比如調(diào)用方法焕梅、屬性、下標索引等前面需要加上一個?卦洽,如果是nil值贞言,也就是Optional.None,會跳過后面的操作不執(zhí)行阀蒂,如果有值该窗,就是Optional.Some,可能就會拆包(unwrap)蚤霞,然后對拆包后的值執(zhí)行后面的操作酗失,來保證執(zhí)行這個操作的安全性,比如:

let hashValue = strValue?.hashValue

strValue是Optional的字符串争便,如果strValue是nil级零,則hashValue也為nil,如果strValue不為nil,hashValue就是strValue字符串的哈希值(其實也是用Optional wrap后的值)

另外奏纪,?還可以用在安全地調(diào)用protocol類型方法上鉴嗤,比如:

@objc protocol Downloadable {
@optional func download(toPath: String) -> Bool;
}

@objc class Content: Downloadable {
    //download method not be implemented
}

var delegate: Downloadable = Downloadable()
delegate.download?("some path")

因為上面的delegate是Downloadable類型的,它的download方法是optional序调,所以它的具體實現(xiàn)有沒有download方法是不確定的醉锅。Swift提供了一種在參數(shù)括號前加上一個?的方式來安全地調(diào)用protocol的optional方法。

另外如果你需要像下面這樣向下轉(zhuǎn)型(Downcast)发绢,可能會用到 as?:

 if let dataSource = object as?         UITableViewDataSource {
let rowsInFirstSection  = dataSource.tableView(tableView, numberOfRowsInSection: 0)
}

到這里我們看到了?的幾種使用場景:
1.聲明Optional值變量
2.用在對Optional值操作中硬耍,用來判斷是否能響應后面的操作
3.用于安全調(diào)用protocol的optional方法
4.使用 as? 向下轉(zhuǎn)型(Downcast)
另外,對于Optional值边酒,不能直接進行操作经柴,否則會報錯:

//error: 'String?' does not have a member named   'hashValue'
//let hashValue = strValue.hashValue
//                ^        ~~~~~~~~~

let hashValue = strValue.hashValue

上面提到Optional值需要拆包(unwrap)后才能得到原來值,然后才能對其操作墩朦,那怎么來拆包呢坯认?拆包提到了幾種方法,一種是Optional Binding氓涣, 比如:

if let str = strValue {
    let hashValue = str.hashValue
}

還有一種是在具體的操作前添加!符號牛哺,好吧,這又是什么詭異的語法?!

直接上例子劳吠,strValue是Optional的String:

let hashValue = strValue!.hashValue

這里的!表示“我確定這里的的strValue一定是非nil的引润,盡情調(diào)用吧” ,比如這種情況:

if strValue {
    let hashValue = strValue!.hashValue
}

{}里的strValue一定是非nil的痒玩,所以就能直接加上!淳附,強制拆包(unwrap)并執(zhí)行后面的操作。 當然如果不加判斷凰荚,strValue不小心為nil的話燃观,就會出錯褒脯,crash掉便瑟。

考慮下這一種情況,我們有一個自定義的MyViewController類番川,類中有一個屬性是myLabel到涂,myLabel是在viewDidLoad中進行初始化。因為是在viewDidLoad中初始化颁督,所以不能直接聲明為普通值:var myLabel : UILabel践啄,因為非Optional的變量必須在聲明時或者構(gòu)造器中進行初始化,但我們是想在viewDidLoad中初始化沉御,所以就只能聲明為Optional:var myLabel: UILabel?, 雖然我們確定在viewDidLoad中會初始化屿讽,并且在ViewController的生命周期內(nèi)不會置為nil,但是在對myLabel操作時,每次依然要加上!來強制拆包(在讀取值的時候伐谈,也可以用?烂完,謝謝iPresent在回復中提醒),比如:

myLabel!.text = "text"
myLabel!.frame = CGRectMake(0, 0, 10, 10)
...

對于這種類型的值诵棵,我們可以直接這么聲明:var myLabel: UILabel!, 果然是高(hao)大(gui)上(yi)的語法!, 這種是特殊的Optional抠蚣,稱為Implicitly Unwrapped Optionals, 直譯就是隱式拆包的Optional,就等于說你每次對這種類型的值操作時履澳,都會自動在操作前補上一個!進行拆包嘶窄,然后在執(zhí)行后面的操作,當然如果該值是nil距贷,也一樣會報錯crash掉柄冲。

var myLabel: UILabel! //!相當于下面這種寫法的語法糖
var myLabel: ImplicitlyUnwrappedOptional<UILabel>
那么!大概也有兩種使用場景

1.強制對Optional值進行拆包(unwrap)
2.聲明Implicitly Unwrapped Optionals值,一般用于類中的屬性


解釋二:
從IB中拖線的控件對應的變量:

// 系統(tǒng)自帶
@IBOutlet weak var display: UILabel!

// 如果這樣
@IBOutlet weak var display: UILabel?

?表示display是一個可選類型(optionals)忠蝗,!表示對可選類型進行強制解包羊初,如果解包的變量是nil,程序就會崩潰.
系統(tǒng)自帶的相當于在xib解檔賦值的時候什湘,進行了強制解包长赞;而后面修改后,賦值時沒有進行強制解包闽撤,所以后面使用display時得哆,需要這樣使用以獲取其屬性--

 display!.text

以上的兩種解釋第一種比較詳細, 第二種凡是有做過一些小程序的人, 都能理解,簡單易懂

3 swift字符和字符串

3.1字符

// OC當中的字符 
char charValue = 'a';
// swift當中的字符
var charValue: Character = "a"

Swift和OC字符不一樣
1.Swift是用雙引號
2.Swift中的字符類型和OC的也不一樣
OC中的字符占一個字節(jié), 因為它只包含ASCII表中字符
而Swift中的字符除了可以存儲ASCII表中的字符還可以存儲Unicode字符,
OC的字符是遵守ASCII標準的. Swift的字符是遵守Unicode標準的
所以可以存放世界上所有國家語言的字符(大部分)

// OC中
char charValue = '高';// 錯誤
// Swift中
var charValue: Character = "高' // 正確

注意:雙引號只能存放一個字符, 如下寫法是錯誤的

var charValue : Character = "ab"

3.2字符串

C:

char *stringV = "ab";
char *stringV2 = "cd";

OC:

NSString *stringV = "ab";

Swift:

var stringV = "ab"
var  stringV:String = "ab"

C語言中的字符串都是以\0結(jié)尾的, 例如

char *StringV = "abc\0def";
printf("%s", StringV);

輸出結(jié)果:abc

OC語言中的字符串也是一\0結(jié)尾的 例子就不再舉了
Swift中的字符串和C語言/OC語言中的字符串是不一樣的

var StringV = "abc\0def"
print(StringV)

輸出結(jié)果:abcdef
將兩個字符串合并在一起:
OC

NSMutableString *str1 = [NSMutableString stringWithString:@"abc"];
NSString *str2 = @"def";
[str1 appendString: str2];
NSLog(@"%@", str1);

輸出結(jié)果:abcdef

Swift:

var str1 = "jian"
var str2 = "shu"
var str = str1 + str2
print(str)

輸出結(jié)果: jianshu

3.3字符串比較

OC:

// 方法一:
NSString *str1 = @"abc";
NSString *str2 = @"abc";
if ([str1 compare: Str2] == NSOrderedSame)
{
    NSLog(@"相等");
}else{
    NSLog(@"不相等");
}
// 方法二:
NSString *str1 = @"abc";
NSString *str2 = @"abc";
if([str1 isEqualToString: str2])
{
    NSLog(@"相等")
}else{
    NSLog(@"不相等");
}

輸出結(jié)果: 相等

Swift:

Swift: (== , != , >= , <= )這些是Swift中字符串的比較符號, 和C語言的strcmp一樣的是逐一比較

var str1 = "abc"
var str2 = "abc"
if str1 == str2
{
    print("相等")
}else{
    print("不相等")
}

輸出結(jié)果: 相等

var str1 = "abc"
var str2 = "adc"
if str1 >= str2
{
    print("大于等于")
}else{
    print("不大于等于")
}

輸出結(jié)果: 大于等于

3.4大小寫轉(zhuǎn)換

OC:

NSString *str = @"abc";
NSLog(@"%@", [str uppercaseString]);
NSLog(@"%@", [str lowercaseString]);

輸出結(jié)果: ABC
abc

Swift:

var str = "abc"
print(str.uppercaseString)
print(str.lowercaseString)

輸出結(jié)果: ABC
abc

3.5轉(zhuǎn)換成基本數(shù)據(jù)類型

OC:

NSString *str = @"250";
NSInteger number = [str integerValue];
NSLog(@"%tu", number);

輸出結(jié)果: 250

如果str不能轉(zhuǎn)換為整數(shù), 那么可選類型返回nil
str = "250sb" 不能轉(zhuǎn)換所以可能為nil
這句話, 我也不是很理解,望各位讀者見諒, 如果有自己的想法, 歡迎評價

var str = "250"
var number: Int? = Int(str)
if number != nil
{
    // Swift以前的版本中的printIn會自動拆包, 現(xiàn)在的不會
    print(number!)
}

作者說

本片文章介紹的知識點并不是多, 主要就是關于!與? 他們的使用, 目前的我, 也沒有辦法熟練的使用, 只是當報錯的時候, 再解決, 抱歉.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市哟旗,隨后出現(xiàn)的幾起案子贩据,更是在濱河造成了極大的恐慌,老刑警劉巖闸餐,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件饱亮,死亡現(xiàn)場離奇詭異,居然都是意外死亡舍沙,警方通過查閱死者的電腦和手機近上,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拂铡,“玉大人壹无,你說我怎么就攤上這事「兴В” “怎么了斗锭?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長失球。 經(jīng)常有香客問我岖是,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任豺撑,我火速辦了婚禮作箍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘前硫。我一直安慰自己胞得,他們只是感情好,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布屹电。 她就那樣靜靜地躺著阶剑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪危号。 梳的紋絲不亂的頭發(fā)上牧愁,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天,我揣著相機與錄音外莲,去河邊找鬼猪半。 笑死,一個胖子當著我的面吹牛偷线,可吹牛的內(nèi)容都是我干的磨确。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼声邦,長吁一口氣:“原來是場噩夢啊……” “哼乏奥!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起亥曹,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤邓了,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后媳瞪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體骗炉,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年蛇受,在試婚紗的時候發(fā)現(xiàn)自己被綠了句葵。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡龙巨,死狀恐怖笼呆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情旨别,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布汗茄,位于F島的核電站秸弛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜递览,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一叼屠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧绞铃,春花似錦镜雨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至菲盾,卻和暖如春颓影,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背懒鉴。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工诡挂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人临谱。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓璃俗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親悉默。 傳聞我的和親對象是個殘疾皇子旧找,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容