
参考:http://www.jb51.cc/article/p-nvepcmct-dy.html
1.常量和变量的定义。
常量使用let 进行约束, 变量使用var来约束,相信大家对var并不陌生,如早期的VB, pascal,Js等都会有这样的定义。
swift对常量,和变量的约束,编译更加精确,有时候用户可以不需要声明某个常量是什么类型,像通常 声明一个变量 int b = 0;
而 在swift中使用var b=0 即可,swift可根据初始化的值进行判断是变量是什么类型,如果var 中没有指定足够的信息(当然是机算判断变量类型的信息时,)可以使用分号进行加以说明,
变量的声明与使用
let implicitInteger = 70 //会自动识别为integer
let implicitDouble = 70.0
let explicitDouble: Double = 70 //加上类型说明
变量的声明与使用
var myVariable = 42
myVariable = 50
var explicitvariable:Double = 60
//下面编译不会通过的,因为等式左右的数据类型不一样,而且不能隐式转换
//由此可以说swift的数据类型是安全的
var uint32Value:UInt32=uint8Value+uint16Value
//swift的类型转换//swift不允许不同的数据类型,进行转换和赋值的,即便是Int的子类let doubleValue:Double=12.345var intvar:Int=3var floatVar:float=23.3456;//强转//不同的数据类型是可以强转的,同一数据类型不同的子集也是不可以强转的intvar=Int(doubleValue)print(intvar)floatVar=float(doubleValue)print(floatVar)
常量变量可以用中文,这个略屌..
let 我老婆="我现在的女朋友"println(我老婆)
还有一点有意思是变量或常量的命名名称,几乎支持各种字符,包知unicode字符。
//注意1>加转义字符的空 \反斜杠 \t水平制表符 \r回车 \n换行 \''双引号 \'单引号//
注意2>单字节unicode标量 \XNN,nn 是两位十六进制数
两字节的Unicode标量\uNNNN,nnnn是四位十六进制数字
四字节Unicode标量 \Unnnnnnnnn,nnnnnnnn是八进制数字
let dollorSign="\u{24}"let blackHeart="\u{2645}"let sparklingHeart="\u{0001F496}"
let constvalue = 70 ;let 我爱你中国 = "我要写中国的 *** 作系统" ;println(constvalue) ;println(我爱你中国);
还有一点有意思是变量或常量的命名名称,几呼支持各种字符,包知unicode字符。
上面代码写在一行时,需要用分隔号分开,如果不使用分号,可以使用换行符:
let constvalue = 70 let 我爱你中国 = "我要写中国的 *** 作系统" println(constvalue) println(我爱你中国)
//1>常量和变量 let 和var 类型推断//2>pritln 打印插值运算//3简单的数据类型// 3.1 整数(Integer) Int8,UInt8,Int16,UInt16,Int32,UInt32,Int64,UInt64,//可以用.max 和min 来取得上下限//// 3.2 整型 在一个32位平台,UInt的尺寸和UInt32是一样的 //在一个64位平台中UInt 和UInt64是一样的// 3.3浮点类型 Double 表示64位的浮点数 精确度低于6位十进制数字 //float 表示32位的浮点数 精确度低于15位十进制数字// 3.4 字符/字符串类型 Char/String //类型别名 typealiastypealias MYINT=Intlet mychar:Character="L" //双引号必须是一个字符,两个会报错print(mychar);let mystr:String="hello"// 3.5布尔类型// 只有两个值 true falselet mybool:Bool=true;let youBoll=false;//3.6字面值// 3.6.1 整型let decimalinteger=17//十进制let binaryInteger=0b0001 //二进制let Octalinteger=0174567 //八进制let hexadecimalinteger=0x11 //十六进制print(decimalinteger)print(binaryInteger)print(Octalinteger)print(hexadecimalinteger) //全是十进制// 3.6.2浮点类型let exponentDouble=1.21875e1//科学计数法 //十进制浮点数let hexadecialDouble=0xC.3p0 //十六进制浮点数print(exponentDouble)print(hexadecialDouble)// 3.6.3 字符let char:Character="c"//3.6.4字符串let something:String="hello world "//注意1>加转义字符的//1.种类,常量字符串let,和变量字符串var//2初始化为空的字符串// 1> "" let emptyStr = ""print(emptyStr) //打印然而什么都没有// 2>String()let emptyString = String()print(emptyString) //打印然而都没有// 3使用现成的字符串初始化let string = "hello"let newString=string;//4计算字符串中字符个数(淘汰)//print("string的个数为\(count(string))")// (淘汰)//遍历(淘汰)//for character in string {//print(character)//}//5.字符串和字符的组合 或者字符串和字符串的组合// + +=//6.字符串的判断string.isEmpty //判空string.hasPrefix("123") //前缀string.hasSuffix("1234")//后缀//判断相等就用 == str1 == str2//7.大小写转换string.uppercaseString //所有字符转化大写string.lowercaseString //所有字符转化小写//8.Unicode 编码//Unicode 是针对编码和文本的国际标准,几乎可以显示世界所有的语言//swift 语言的swift 的字符串完全兼容Unicode,支持不同的Unicode编码//在Unicode 每一个字符都可表示一个或者多个Unicode scalars,一个Unicode scalar 是一个21位数//包含了UTF-8,UTF-16let str1 = "\u{00000061}"var str2:String = "chicken\u{0001F425}"print(str1)print(str2)for char in str2.utf8 {print(char) }for char in str2.utf16 { print(char) }for scalar in str2.unicodeScalars { print(scalar.value) } 空 \ 反斜杠 \t 水平制表符 \r 回车 \n换行 \''双引号 \'单引号//注意2>单字节unicode标量 \XNN,nn 是两位十六进制数 //两字节的Unicode标量\uNNNN,nnnn是四位十六进制数字 //四字节Unicode标量 \Unnnnnnnnn,nnnnnnnn是八进制数字let dollorSign="\u{24}"let blackHeart="\u{2645}"let sparklingHeart="\u{0001F496}"print(dollorSign)print(blackHeart)print(sparklingHeart)print("Hello,World!")//3.6.5 bool字面值let bol=false;
\()
3.字符串串接及类型转换
\(apples)
大家可能用OC都有一个想骂人的串接问题,如 在nsstring *a = "hello" 串接 " world",常常使用stringbyappendstring ,或使用stringWithFormat:"%@,%@" 来串接,有没有?而不能使用"+" *** 作符。真难过,实在难过,特别是对于C/C++,PASCAL,JAVA 甚至更多高级语言都是支持“+”号 *** 作符。唯有OC特别,搞得我一个同事说,想学习一下IOS,但语言太另类了,其实啥语言都大差不差,习惯就好。现在好了,swift来了,他也支持“+”号 *** 作符了。如:
“let label = "The wIDth is "
let wIDth = 94
let wIDthLabel = label + String(wIDth)”
同时大家也可能发现了,wIDth是整型,在这里被显式的强制类型转换为字符型,这里有个疑问,就是 如果没有进行强制类型转换,这let wIDthLabel = label + wIDth这样是否可以编译过呢?编译器会不会隐式的进行转换呢,我也好期待,因为没有 *** 作环境,只是在看swift官方学习文档中的,因此留在这里,后续有环境进行验证一下。
接下来说说这个类型转换,咋看又像在抄pascal 或java 的语法, c/c++ 的风格的都是(类型)变量,如(char *) var ,(double) var,而不会写成double(var),oc的写法,与c/C++的很像。没太搞明白为毛,即整合c/c++的,又特地搞个风格别致的,当然,什么都不要紧,习惯就好。对吧,大伙说。
不过swift似呼也嗅到了什么,也提提供了另一种参变量使用"\(apples + oranges)" *** 作符,其中括号中的还支持表达式 *** 作。至于反斜扛 *** 作嘛,就有点像大家在C/C++ 中的换行串接时,在行尾加上的\的含议差不多。看一下官方给出的例子:
“let apples = 3
let oranges = 5
let appleSummary = "I havecopyapples."
let fruitSummary = "I havepIEces of fruit.”
可能用文字表达不出\()的意思,其实就是参数变量 把上面四句翻译为oc 则为
NSInteger apples = 3;
NSInteger oranges = 5;
Nsstring *appleSummary = [Nsstring stringWithFormat:@"I have %d apples",apples];
经试验:
[cpp] view plain letconstvalue=70 "我要写中国的 *** 作系统" let我爱你中国=letok=String(constvalue)+我爱你中国 "字符串串接\(我爱你中国)" letokgood=println(okgood)输出为: 数据类型别名:
typealias AudioSample = UInt16
字符串串接我要写中国的 *** 作系统
oc /c/c++都使用typedef 来约束新的类型别名
而swift 则使用typealias
letwiseWords=
字符串常量可以包括下面这些特殊字符:
空字符\0,反斜杠\,制表符\t,换行符\n,回车符\r,双引号\”和单引号\’
单字节Unicode字符,\xnn,其中nn是两个十六进制数
双字节Unicode字符,\unnnn,其中nnnn是四个十六进制数
四字节Unicode字符,\Unnnnnnnn,其中nnnnnnnn是八个十六进制数
copy "\"Imaginationismoreimportantthanknowledge\"-Einstein" //"Imaginationismoreimportantthanknowledge"-Einstein "\x24" letdollarSign=//$,UnicodescalarU+0024"\u2665" letblackHeart=//♥,UnicodescalarU+2665"\U0001F496" letsparklingHeart=//,UnicodescalarU+1F496初始化一个空字串
varemptyString=
copy "" //emptystringliteral//initializersyntax varanotherEmptyString=String()同时可以使用isEmpty来判断字符串是否为空,这点真的很像pascal,delphi就是这样检测的。 if
copy emptyString.isEmpty{ "Nothingtoseehere") println(}在swift中字符串不是指针,而是实际的值,因此,在Swift中,一个String类型就是一个实际的值,当定义一个新的String,并且将之前的String值拷贝过来的时候,是实际创建了一个相等的新值,而不是仅仅像指针那样指向过去。同样在函数传递参数的时候,也是传递的实际值,并且创建了一个新的字符串, 后续的 *** 作都不会改变原有的String字符串 。 单个字符的声明,像c/c++中使用 char,而swift中则使用:
letyenSign:Character=
copy "¥" 通过for-in循环,可以遍历字符串中的每一个字符 for
copy characterin "Dog!"{println(character)} 字符串长度的统计,可以使用全局函数countElements可以计算一个字符串中字符的数量,这点与其它语言length好像有点不同。
copy "Koala,Snail,Penguin,Dromedary" "unusualMenageriehas\(countElements(unusualMenagerie))characters") println(//prints"unusualMenageriehas40characters" 字符串与单个字符,可以使用+,+= *** 作将字符串和字符串接在一起。这点与其它语言稍先进一点。 letquotation=
字符串的比较使用 ==
copy "We'realotalike,youandI." "We'realotalike,youandI." letsameQuotation=quotation==sameQuotation{"Thesetwostringsareconsideredequal" if) println(} //prints"Thesetwostringsareconsideredequal"swift还保留了oc中的前后缀函数hasPrefix和hasSuffix //输出”Thesetwostringsareconsideredequal”
lettestUncode=
大小写字符串使用uppercaseString 和 lowercaseString
unicode :
Swift 支持多种不同的方式取得Unicode字符串.
你可以使用for-in语句遍历字符串,来获得每一个字符的Unicode编码值。这个过程已经在字符(Working with Characters)描述过了。
或者,下面三个描述中使用合适的一个来获得一个字符串的值
UTF-8字符编码单元集合使用String类型的utf-8属性
UTF-16字符编码单元集合使用String类型的utf-16属性
21位Unicode标量集合使用String类型的unicodeScalars属性
如例子:
copy "Dog!狗" forcodeUnitintestUncode.utf8{ "\(codeUnit)") print(}"\n" ) print(codeUnitintestUncode.utf16{ //6811110333231139151 forscalarintestUncode.unicodeScalars{ //681111033329399"\(scalar.value)" for) print(在utf-8中,中文的"狗"占三个字节,而在utf-16 及标量(utf-32)中正好可以一个字节就装得下。 //681111033329399
//1可变的数组和不可变的数组//2.空数组的初始化// 1>let a:[Int]=[]// 2let b:[Int]=[Int]()//3.非空数组的初始化// 1>let a1:[Int]=[1,2,3]let b1 = [1,3,56]// 2>专用语法初始化var db = [Double](count: 5,repeatedValue: 1.0)print(db) //[1.0,1.0,1.0]// 3>数组初始化数组 var db1 = db//4.数组的 *** 作// 1>元素的个数print(db1.count);// 2>判空print(print(db.isEmpty))// 3> == 判断是否相同print(a1==b1)// 4>复制//var db2 = db.copy();var strArr:AnyObject = ["12","sdf","sdf"]var strArr1=strArr.copy()// 5追加// += 或者 append()// 6插入 insert// 7读取值 a[0] 索引// 8 修改值// 1> 单个值下表// 2> 一系列 a[2...5] 必须是一个封闭或者半封闭范围// 9删除值// remove // 10遍历数组// 1>遍历值for item in db { print(item)}
4.数组,字典
在swift的书中说,数组和字典都使用“[]”中括符,并可以通过索引或KEY /VALUE的方式存储。见官方例子:
“var shoppingList = ["catfish","water","tulips","blue paint"] //声明一个四元素的数组变量
shoppingList[1] = "bottle of water"//数组使用//重新将元素2的进行赋值
var occupations = [
"Malcolm": "Captain",
"Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations” //动太的添加一个jayne的key值为Public Relations
这个k/V的数组是否长的有点像JOSN啊。反正我看像,还可以动太的添加哦,
创建一个空的数组如: let emptyArray = String[]() //又是中括号又是圆括符的,看得真让人眼花。不过swift中说了,如果不需要指字类型,则数组可以直接使用"[ ]"
进行。如: shoppingList = [] ,字典则使用 “ [ :]” 来设为空字典。
另外字典增加了一个定议模式,有点像C++中的vector 或map之类的,可以指字 k/v的类型吧。见例:
“let emptyDictionary = Dictionary<String,Float>()”
整体感觉上还是比较像C++吧。
copy varthreeDoubles=Double[](count:3,repeatedValue:0.0) //初始化时指定长度确定类型的println(threeDoubles) varanotherThreeDoubles=Array(count:3,repeatedValue:2.5) //不确定类型的println(anotherThreeDoubles) "lenovo" //varcomputerList=String[]()//创建一个空的数组, varcomputerList:String[]=["dell"]!computerList.isEmpty //varcomputerList=["lenovo","dell"]//与上等效//判断是否为空数组 if{ "数组共有\(computerList.count)元素." //数组长度) println("元素分别为\(computerList.description)") println(//使用description访问 computerList=[] //直接置空"空数组\(computerList)" ) println("sony" //动态追加元素) computerList.append("追加后为:\(computerList)") println(//真接访问"acer" computerList+="追加后为:\(computerList.description)") println("HP" //可以一次追加一个数组, computerList+=["samsung","Apple"]"追加数组后为:\(computerList)") println("Haier", varitems=["东之"]computerList+=items"追加数组后为:\(computerList)" ) println("你访问索引3的元素\(computerList[3])" //下标访问) println("修改前为:\(computerList[2])" //使用下标进行修改元素值) println("SONY" computerList[2]="修改后为:\(computerList[2])") println( //通过闭包访问一次修改多个值 //注意[4..6]是半闭包即只包括改修4,5而不包括6"惠普" //使用[4...6]是全闭包,可以修改4,5,6, computerList[4...6]=["三星","a","b","c"]//元素超出部分会直接追加在末尾"修改后为:\(computerList)") println("computer" //插入元素,atIndex:0) computerList.insert("插入后为:\(computerList)") println(letdel=computerList.removeAtIndex(0) //通过索引进行删除元素"删除的元素为:\(del)" ) println(letdellast=computerList.removeLast() //移除最后一个元素"最后的元素为:\(dellast)" ) println(itemincomputerList //遍历数组println(item) for //如果需要每一个元素的整形的索引值,使用enumerate函数代替会更方便(index,value)inenumerate(computerList) //enumerate函数对于每一个元素都会返回一个包含元素的索引和值的元组{ for"Item\(index+1):\(value)" ) println(}字典的使用
//1 空字典的初始化var dic=Dictionary<Int,Int>()//2初始化非空字典var dic1=[1:"s",2:"w"]//3 获取元素的个数print(dic1.count)//4读取键 对应的值print(dic1[1])//5添加元素dic1[3]="t" //添加键为3 值为 "t" 的键值对//6修改键关联的值// 1>dic1[3]="你好"print(dic1)// 2>dic1.updateValue("呵呵",forKey:2)print(dic1)//7 删除键// 1> nil dic1[3]=nil //键为3,的这一键值对删除// 2>removeAll() 删除所有// 3>removeValueForKey()//遍历// 1>遍历值for dicValue in dic1.values { print(dicValue)}// 2>遍历键for dickey in dic1.keys { print(dickey)}//遍历键值 for (key,value) in dic1 { print("\(key):\(value)")}
//字典
copy //Dictionary<KeyType,ValueType>唯一的限制就是KeyType必须是可哈希的(hashable)"TYO" //varnamesOfIntegers=Dictionary<Int,String>()//创建空字典: varairport:Dictionary<String,String>=["Tokyo","DUB":"Dublin"]"TYO": varairports=["Tokyo","DUB":"Dublin"]"字典包函元素有\(airports.count)" //字典元素) println("LHR" //使用key添加value]= airports["London""添加元素后\(airports)") println("LHR" //使用key修改]= airports["LondonHeathrow""修改元素后\(airports)") println(letoldValue=airports.updateValue( /*updateValue(forKey:)方法如果键不存在则会设置它的值,如果键存在则会更新它的值,和下标不一样是 updateValue(forKey:)方法如果更新时,会返回原来旧的值rThisenablesyouto可以使用这个来判断是否发生了 updateValue(forKey:)方法返回一个和字典的值相同类型的可选值.例如, 如果字典的值的类型时String,则会返回String?或者叫“可选String“, 这个可选值包含一个如果值发生更新的旧值和如果值不存在的nil值。 */"DublinInternational" if,forKey:"DUB")"TheoldvalueforDUBwas\(oldValue).") println("最新值\(airports)") println(letairportName=airports[ //判空"DUB" if]"Thenameoftheairportis\(airportName).") println("Thatairportisnotintheairportsdictionary." else) println("APL" //字典移除]= airports["AppleInternational""当前字典:\(airports)") println("APL"]=nil airports["移除后字典:\(airports)") println(letremovedValue=airports.removeValueForKey( //也可以使用removeValueForKey移除"DUB" if)"Theremovedairport'snameis\(removedValue).") println("TheairportsdictionarydoesnotcontainavalueforDUB.") println((airportCode,airportName)inairports //遍历字典"\(airportCode):\(airportName)" for) println(airportCodeinairports.keys //遍历key"Airportcode:\(airportCode)" for) println(airportNameinairports.values //遍历value"Airportname:\(airportName)" for) println(letairportCodes=Array(airports.keys) //获取所有key转为数组"所有keys为:\(airportCodes)" ) println(letairportNames=Array(airports.values) //获取所有value转为数组"所有values为:\(airportNames)" ) println(enum
4.枚举类型
枚举在swift中可胃得到了很高的提升。不单单只简单的支持Int数据类型,还扩展了支持其它数据类型,一起来探究一下吧
基本语法:
copy CompassPoint{ NorthSouth caseEast caseWest case} case每个case 为一个成员,但多个成员也可以写在一个case里,用逗号分隔 enum
copy Planet{ Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune} case声明及使用
copy vardicection:CompassPointdicection=.East vardirectionToHead=CompassPoint.West directionToHead=.South 与 switch配合使用
vardirectionToHead=CompassPoint.West
copy directionToHead{ .North: switch"Lotsofplanetshaveanorth" case) println(.South:"Watchoutforpenguins" case) println(.East:"Wherethesunrises" case) println(.West:"Wheretheskiesareblue" case) println( //default://如果不需要各个都配置时,可以使用defult} //println("nowhat"); Swift的枚举类型可以由一些数据类型相关的组成,如果需要的话,这些数据类型可以是各不相同的。枚举的这种特性跟其它语言中的奇异集合 如:
枚举的关联值支持
enum
copy Barcode{ UPCA(Int,Int,Int)QRCode(String) case} case然后可以使用任何一种类型来创建如:
varproductBarcode=Barcode.UPCA(8,85909_51226,3)
copy 此示例创建一个名为productBarcode新的变量,并与相关联的元组值赋给它Barcode.UPCA的值(8,8590951226,3)。 也可以使用:
productBarcode=.QRCode(
copy "ABCDEFGHIJKLMNOP" )不同的条码类型像以前一样可以使用一个switch语句来检查,但是这一次相关的值可以被提取作为switch语句的一部分。您提取每个相关值作为常数(let前缀)或变量(var前缀)不同的情况下,在switch语句的case代码内使用
switch
copy productBarcode{ .UPCA(letnumberSystem,letidentifier,letcheck):"UPC-Awithvalueof\(numberSystem),\(identifier),\(check)." case) println(.QRCode(letproductCode):"QRcodewithvalueof\(productCode)." case) println(@L_404_23@ 如果所有的枚举成员的关联值的提取为常数,或者当所有被提取为变量,为了简洁起见,可以放置一个var,或let标注在成员名称前
copy enum ASCIIControlCharacter:Character{ Tab="\t" case//这里设置值要与<span>Character类型相对应</span>LineFeed="\n" caseCarriageReturn="\r" case} enum copy ASCIIControlCharacter:Int{ Tab=10LineFeed=20 caseCarriageReturn=30 case} case同样还可以使枚举跟c/C++,java,pascal phyon等高级语言的效果一样。只需要设置第一个值后,后面的值会类推。 enum
copy Planet:Int{ }后面的成员会自增。 caseMercury=1,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> 同时swift还提供了访问枚举成中中的原始值,使用toRaw()如:
letearthsOrder=Planet.Earth.toRaw()
copy 另外,还提供了一个检查访问,fromRaw() //earthsOrderis3 letpossiblePlanet=Planet.fromRaw(7)
copy 使用枚举的fromRaw方法来试图找到一个特定的原始值枚举成员。这个例子识别Uranus的位置通过原始值为7:然而,并非所有可能的Int值都会找到一个匹配的星球。正因如此,该fromRaw方法返回一个可选的枚举成员。在上面的例子中,是possiblePlanet类型Planet?或“可选的Planet”。 //possiblePlanetisoftypePlanet?andequalsPlanet.Uranus如果你试图找到一个Planet为9的位置,通过fromRaw返回可选的Planet值将是无:因此在配合switch时可以这样:
letpositionToFind=9
copy letsomePlanet=Planet.fromRaw(positionToFind){ somePlanet{ if.Earth: switch"Mostlyharmless" case) println(:"Notasafeplaceforhumans" default) println(else{ }"Thereisn'taplanetatposition\(positionToFind)") println(
//1.1 元//目标数值的个数//1.2赋值运算符和表达式let (x,y)=(5,"Hello");print(x);print(y);//1.3运算和表达式// + - * / % 基本运算符,关于 负号,跟数学表达式是一样的//关于/ 分母不能是0var a1=9/4var a2=9.00/4print(a1) //表达式中都是整数,结果也是整数print(a2) //当表达式有一个为浮点数,结果页浮点数//关于%var b1=9%4 //正数var b2=(-9)%(-4)//负数var b3=(-9)%4 //负数var b4=9%(-4) //正数print(b1)print(b2)print(b3)print(b4)//注意浮点数取模,也是浮点数(特有)var a=8%2.5print(a)//1.4自增,自减 ++ --//1.5一元减运算符let three = 3let minusThtree = -three //注意空格print(minusThtree)//1.6一元加运算let asloMinusThree = +minusThtree; //只是为了对齐代码,不改变数值print(asloMinusThree)//1.7位运算// &// |// ^ 按位异或 相同为0 不同为1// ~ 按位取反// << 按二进制全部左移N位,右补0// >> 按二进制右移N位,对于无符号位,高位补零//1.8溢出运算符 &+ &- &* &///上溢出var max=UInt8.max; //255max = max &+ 1print(max) //0 &+n ===n-1//下溢出var min=UInt8.min; //0min = min &- 1print(min) //255 &- n ==255-(n-1)//除 0 溢出(待研究)//1.9 逻辑运算符 && || ! let xx = !(10>7)print(xx) //值只能是true 或者false//1.10 范围运算符//1. 封闭运算for index in (1...5) { print(index)}//2.半封闭运算for index in (1..<5) { print(index) //不包括5}//1.11 求字节运算符let size=sizeof(Int)print(size)//1.12 可选类型强制解析var value:Int?=5print(value) //可选值var bb = value! - 9 //强制解析print(bb)//1.13 类型转换//swift 不存在隐式转换//1整数的转换,整数有 8种,不一样要转换一下//2 整数和浮点数的转换 //prints"Thereisn'taplanetatposition9"
5表达式。
varconstvalueB=200
if/swicth
“let individualScores = [75,43,103,87,12]
var teamScore = 0
for score in individualScores {
if score > 50 {
teamScore += 3
} else {
teamScore += 1
}
}”
teamScore
为什么都不加括号了?对于多个表达式,还是这样长蛇阵么?
另外书中有这一段“In an if statement,the conditional must be a Boolean expression—this means that code such as if score { ... } is an error,not an implicit comparison to zero.”
个人理解是,如果在一个条件语句中,条件值必须是BOOL表达式的,因为非BOOL表达式不会隐式的与0进行比较,这点可能与传统的if有点不同吧。
经验证:多个条件也不需要用括号的。不过,如果你想要表达式正确,还是要按照运算优先级。
copy letconstvalue=70 constvalueB==0&&constvalue>60||constvalue!=20 "true" if) println("false" else) println(}别外像:
if
copy constvalueB }对 constvalueB copy 这样的条件,在swift中已经通不过了,对条件判断也更别严格了。 letcount=3_000_000_000_000
再来看一下switch,这个总算有点点进步了,以前的switch大多只支持int或枚举类型,现在swift中把switch语句的表达式判断类型上进行了扩展。其次,每个case不再需要写break;这点不错。
“let vegetable = "red pepper"
switch vegetable {
case "celery":
let vegetableComment = "Add some raisins and make ants on a log."
case "cucumber","watercress":
let vegetableComment = "That would make a good tea sandwich."
case let x where x.hasSuffix("pepper"):
let vegetableComment = "Is it a spicy \(x)?"
default:
let vegetableComment = "Everything tastes good in soup."
}”
哈哈,看到没有,没有break哦。。。冒似少了几个B的代码。
switch语句的case中可以匹配一个数值范围
copy "starsintheMilkyWay" letcountedThings=varnaturalCount:Stringcount{ 0: switch"no" case naturalCount=1...3:"afew" case naturalCount=4...9:"several" case naturalCount=10...99:"tensof" case naturalCount=100...999:"hundredsof" case naturalCount=1000...999_999:"thousandsof" case naturalCount=:"millionsandmillionsof" default naturalCount="Thereare\(naturalCount)\(countedThings).") println(case中还可以直接测试元组是否符合相应的条件,_可以匹配任意值
letsomePoint=(1,1)
copy somePoint{ (0,0): switch"(0,0)isattheorigin" case) println("(\(somePoint.0),0)isonthex-axis") case(_,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> println()(-2...2,-2...2): ) case) 在case匹配的同时,可以将switch语句中的值绑定给一个特定的常量或者变量,以便在case的语句中使用。比如 //prints"(1,1)isinsidethebox"
letanotherPoint=(2,0)
copy anotherPoint{ "onthex-axiswithanxvalueof\(x)" switch) case(letx,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> println("onthey-axiswithayvalueof\(y)") println(let(x,y):"somewhereelseat(\(x),\(y))" case) println( //prints"onthex-axiswithanxvalueof2"enum
思考:如果没有defalut:会是什么样的?有环境验证一下。
验证后有几个有意思的地方:
一,对成员具有完整性检测:如:
copy CompassPoint:Int{ //预先指定为West vardirectionToHead=CompassPoint.WestdirectionToHead{.North: switch"Lotsofplanetshaveanorth" case) println(.South:"Watchoutforpenguins" case) println(.East:"Wherethesunrises" case) println(}这里编译期会报错,提示未找到West。 可以通过以下两种方式进行修正:
"Wherethewest"
copy ); println(} } copy 别外还遇到一个告警问题: var
Compasspoint
如果switch的条件声明在同一个函数内,这时会提示Switchcondition evaluates to a constant
要去除这个,只需要将声明的变量放在函数外就可以
WestdirectionTohead :
//1.选择结构 if / if else 语句 if(1)在swift是不对的//2.选择结构 switch 语句// 1> 不用break,匹配到,自动跳出swith,剩余不会执行// 2>可执行的语句不能为空////let grade = "B"//switch (grade) {////case "A" : print("A")//case "B" "////}// 3>多条件匹配let grade = "B"switch (grade) {case "A,B" : print("A,B")case "B" : print("B")default: print("没找到")}// 4>范围匹配let score = 45switch (score) { case 0...60 : print("不及格")default: print("及格") }// 5>使用元组//case 中可以直接测试元组是否符合相应的条件let point = (1,1)switch point {case (0,0):print("原点")case (_,0):print("\(point.0),0 在x轴上")case (0,_):print("\(point.1),0 在y轴上")case(-2...2,-2...2):print("(\(point.0),\(point.1)) 在矩形内")default: print("(\(point.0),\(point.1)) 在矩形外")}// 6数值绑定// 在switch 匹配中 将switch中的值给某个变量,也可以是常量// 1>let mypoint = (2,2)switch mypoint {case (let x,0):print(" 在x轴上,并且x的值为\(x)")case (0,let y):print(" 在y轴上,并且x的值为\(y)")case(let x,let y):print(" 在其他地方,并且x的值为\(x)并且y的值为\(y)")}let mypoint1 = (2,2)switch mypoint1 {case (var x,var y):print(" 在y轴上,并且x的值为\(y)")case(var x,var y):print(" 在其他地方,并且x的值为\(x)并且y的值为\(y)") }// 2>满足多个条件(淘汰)let mypoint2=(2,0)switch mypoint2 {case let(x,y):print(" 在其他地方,并且x的值为\(x)并且y的值为\(y)")case (let x,并且x的值为\(y)") }// 7使用where 关键字//使用where 增加判断条件let mypoint3=(2,2)switch mypoint3 {case let(x,y) where x==y: print(" 在斜线x==y上,并且x的值为\(x)并且y的值为\(y)")case let(x,y) where x == -y: print(" 在斜线x==-y上,并且x的值为\(x)并且y的值为\(y)")case let (x,y): print(" 这是任意的点") }//3 循环结构 for 语句 //for in// 1>for 后面的是常量,而非变量// 2>省略常量var value = 1var sum = 0for _ in (1...100) { sum += value value++}print(sum)//4.循环结构while//5.跳转结构 continue,break,fallthought// fallthrought 只能在case 下面let grade1 = "A"switch grade1 { case "A": print("90--100") fallthroughcase "B": print("80--90") //fallthroughcase "C": print("70--80") // fallthroughcase "D": print("60--70") fallthroughdefault: print("<< 60") }= .//牢记几个标准的函数//1>绝对值函数abs() 返回值为一个正数或者0 可以获取 -10,10,-1.233,1.233的绝对值//2>最大值函数max()/最小值函数min() 可以数值,也可以字符串或者字符,如果是字符串,则是比较字符串的首字符,如果是字符,则三个数都是字符进行比较,否则会出现错误//3>序列的最大值函数 maxElenment()/最小值函数 minelement(),可以是数值,也可以范围(范围)//let seq=[1,34,45,77,34]//maxElement(seq)//maxElement(1...100)//4>判断序列是否包含指定元素函数contains()// contains(序列,元素)var seq=["swift","hello","world"]if seq.contains("swift") { //比较的时候,会区分大小写 print("包含")}//5.序列排序函数 sort()print("排列前:\(seq)")seq.sortInPlace();print("排列后:\(seq)")//6序列倒序函数 reverse()for i in seq.reverse() { print(i)}//1无参函数func printA() {print("A")}printA();//在swift 中一定要声明之前,调用在后//2有参函数// func funcname(参数1:数据类型,参数二:数据类型)->返回值func nameString(name:String) {}//注意1>参数的个数,和调用传的个数相同// 2>顺序// //3函数参数的特殊情况// 3.1>本地参数func func1(start:Int,end:Int,str:String) {//start,end,str为本地参数}// 3.2,外部参数func joinFunc1(startInt start:Int,endInt end:Int,toString str:String) {}//startInt,endInt,toString 为外部参数// 注意1>调用必须用外部参数// 2>顺序// 3 快速书写 #(淘汰)//func joinFunc2(#start:Int,#end:Int,#toSting:String) {//////}// 3.3 设定内部参数的默认值func joinFunc2(start:Int=0,str:String="默认值") { } //无参默认,传值,可以覆盖掉默认值// 3.4将外部参数设置为默认值func joinString(sting s1:String,toString s2:String="swift",withSting s3:String="---") { print("\(s1)\(s3)\(s2)")}joinString(sting: "hello")// 3.5可变参数 //使一个参数能接受0个或多个指定类型的参数 ...func average(numbers:Double...) { var total:Double=0 for number in numbers { total += number } print(total)}// 注意1>在一个函数中可变参数只能有一个// 2> 多个参数中,可变参数只能排在末尾average(1,5)average(34,45)// 3.6 常量参数和变量参数// 函数中,默认参数都是常量//要想在使用中修改参数的值 加var 了func hhh (var name:String){ name="lichungui" print(name)}hhh("sdfg")// 3.7输入输出参数inout 可改变参数的值func test(inout number:Int) {number=100}var a:Int=0;test(&a)print(a) //神奇 100//4.函数的返回值// 1>一个返回值func range(start:Int,end:Int)->Int {return end-start}// 2>多个返回值(元组)func count(sting:String)->(vowels:Int,consonants:Int,others:Int) { var vowels=0,consonants=0,others=0 return(vowels,consonants,others)}// 3,无返回值//5.函数类型 //1>使用函数类型func add(a:Int,b:Int)->Int { return a+b}var mathFuc :(Int,Int)->Int=add;var mathFuntion=add;//类型推断print(mathFuc(1,5))// 2>使用函数类型作为参数 (淘汰)//func mutiply(a:Int,b:Int)->Int {// // return a*b//}////func printResult(fuc:(Int:Int)->Int,a:Int,b:Int) {//// print(fuc(a,b))//}////printResult(add,a: 3,b: 2)//printResult(mutiply(100,b: 200) )// 3>使用函数类型作为返回值类型//6闭包类型 OC block lambda// 1>闭包表达式// {(参数列表)-> 返回值 in // 语句// }// 2>无参var str={ () in print("aaa")}str()// 3>有参var str1={ (str:String) in print(str) }str1("asdfgh")// 4注意事项// 1>推断类型// 2>省略 return // 3简写参数名(淘汰)//var array=[1,5]////var v1=compare(array,500,{// name: String,day: String > //}//)// 4>trailing 闭包let digitnames = [ 0: "Zero",1: "One",2: "Two",3: "Three",4: "Four",5: "Five",6: "Six",7: "Seven",8: "Eight",9: "Nine" ]let numbers = [16,58,510]let strings = numbers.map { (var number) -> String in var output = ""; while number > 0{ output = digitnames[number % 10]! + output number /= 10 } return output}print(strings) // 打印出来的结果: [Onesix,FiveEight,FiveOneZero]/*** PS:1.在这个例子中,strings 常量被推断为字符串类型数组,即 [String],map 在数组中为每一个元素调用了闭包表达式,您不需要指定闭包的输入参数 number 的类型,因为可以通过要映射的数组类型进行推断,闭包表达式在每次被调用的时候创建了一个字符串并返回。其使用求余运算符 (number %10) 计算最后一位数字并利用 digitnames 字典获取所映射的字符串.2.字典 digitnames 下标后跟着一个叹号 (!),因为字典下标返回一个可选值 (optional value),表明即使该 key 不存在也不会查找失败,在上例中,它保证了 number % 10 可以总是作为一个 digitnames 字典的有效下标 key,因此叹号可以用于强展开 (force-unwrap) 存储在可选下标项中的 String 类型值.*///捕获/*** 在我们使用闭包的时候,其实我们还可以捕获我们自己定义的常量或者变量,即使里面的常量和变量的作用域不存在,闭包仍然可以在闭包函数体内引用或者修改,Swift 最简单的闭包形式是嵌套函数,也就是定义在其他函数体内的函数,嵌套函数可以捕 获其外部函数所有的参数以及定义的常量和变量,让我们一起来看看:*/func makeIncrementor(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementor() -> Int { runningTotal += amount return runningTotal } return incrementor}let incrementBySeven = makeIncrementor(forIncrement: 7)let aaa = incrementBySeven()print(aaa) // 打印出来的结果: 7/*** 1.makeIncrementor 返回类型为 () -> Int,这意味着其返回的是一个函数,而不是一个简单类型值,该函数在每次调用时不接受参数只返回一个 Int 类型的值,关于函数返回其他函 数的内容,请查看 Function Types as Return Types.2.makeIncrementor 函数定义了一个整型变量 runningTotal (初始为 0) 用来存储当前增加总数,该值通过 incrementor 返回.3.makeIncrementor 有一个 Int 类型的参数,其外部命名为 forIncrement,内部命名为 amount,表示每次 incrementor 被调用时 runningTotal 将要增加的量.4.incrementor 函数用来执行实际的增加 *** 作,该函数简单地使 runningTotal 增加 amount,并将其返回.5.Swift 会决定捕获引用还是拷贝值,您不需要标注 amount 或者 runningTotal 来声明在嵌入的 incrementor 函数中的使用方式,Swift 同时也处理 runingTotal 变量的内存管理 *** 作,如果不再被 incrementor 函数使用,则会被清除.*/let incrementBySeven1 = makeIncrementor(forIncrement: 7)let a3 = incrementBySeven1()let b3 = incrementBySeven1()let c3 = incrementBySeven1()print("\(a3),\(b3),\(c3)") // 打印出来的结果: 7,14,21//上面已经很好的解释了,这里我就不多做解释了,还有一个注意点,比如:let incrementBySeven2 = makeIncrementor(forIncrement: 7)let a4 = incrementBySeven2()let b4 = incrementBySeven2()let c4 = incrementBySeven2()print("\(a4),\(b4),\(c4)") // 打印出来的结果: 7,21let incrementByTen = makeIncrementor(forIncrement: 10)let A5 = incrementByTen()let B5 = incrementByTen()let C5 = incrementByTen()print("\(A5),\(B5),\(C5)") // 打印出来的结果: 10,20,30//虽然这两个常量调用的是同一个闭包,但是它们之间所捕获的内容并没有关联,这个需要注意.
6.程序控制结构
String
for - in,for,while,do-while
在for-in 中使用k/v数组,
“let interestingNumbers = [
"Prime": [2,7,11,13],
"Fibonacci": [1,1,8],
"Square": [1,4,9,16,25],
]
var largest = 0
for (kind,numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number
}
}
}
largest”
这个让我感慨的就是每个变量都没有进行显式的声明类型。这也许就是swift所宣存的精确,高效的一个原因之一吧。
另外for 也像pascal一样支持“..”范围 *** 作符。可能熟释DELPHI的朋友一定很深的印象。像这样的for
procedure foroperation
var
char c;
begin
for (c in ['a'..'z']) do
begin
//do something.
end;
end;
官网的例子:
“var firstForLoop = 0
for i in 0..3 {
firstForLoop += i
}
firstForLoop
var secondForLoop = 0
for var i = 0; i < 3; ++i {
secondForLoop += 1
}
secondForLoop”
两个for 过程是一样的,即i都是从0-3. 其实delphi 中还有low() to high() *** 作的,这个swift应该没有吧,如果有的话,我想apple的工程师都应经历了pascal的时代。
值得注意的是:swift中不仅有".." 也有"...",分别代表什么呢。两个点,相当于小于如0..3 等价于 0<=i<3 而使用...则相等于 "<=" 如 0..3 等价于 0<=i<=3
while / do while
“var n = 2
while n < 100 {
n = n * 2
}
n
var m = 2
do {
m = m * 2
} while m < 100
m”
7.函数的语法
condition: Int -> Bool
“func greet() ->{
return "Hello \(name),today is \(day)."
}
greet("Bob","Tuesday")”
通过这个例子,可以看到使用func关键词进行声明,其次 输入参数 使用“变量:类型”的型式,这还真像pascal,你还别说。最有特色的就是这个返回值,参过->符号指定返回的类型。这个也许是C++的地址函问符的一个使用方式吧,每个函数返回的其实都是一个地址块。另外函数如果有多个返回(即传出参数)怎么处理呢?如C/C++ 的使用“**”指针的指针 如 func(char ** outstring) 但在 swift中则:
“func getGasPrices() -> (Double,Double,Double) {
return (3.59,3.69,3.79)
}
getGasPrices()”
其次swift中的函数参数为数组时的写法,也很特别:
“func sumOf(numbers: Int...) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum
}
sumOf()
sumOf(42,597,12)”
内连函数的支持
很多高级语方中都有内连函数,内连函数的使用也是很常见的一种,不仅使得代码执行更加高效,同时也减少了内存碎片。
一起看一下swift的内连函数的写法:
“func returnFifteen() -> Int {
var y = 10
func add() {
y += 5
}
add()
return y
}
returnFifteen()”
还有一个特另的:就是swift还提供了在函数中返回函数来看一下,写法也比较另类:
“func makeIncrementer() -> (Int -> Int) {
func addOne(number: Int) -> Int {
return 1 + number
}
return addOne
}
var increment = makeIncrementer() //increment 可理解为addOne的函数指针
increment(7)”
把这段代码解读一下,首先红色部分是一个函数,入参为整型,返回一个整型的值。 再来看最外层的函数makeIncrementer 没有入参,有返回值,而返回值是使用"()"括起来。
int ->int 这个表示返回的为一个函数地址,该函数有一个int型的输入参数,同时还有一个int 型的返回值参数。这与c/c++的函数指很是有差别。
在swift中,函数也可以作为参数进行传递:(见红色部分)
“func hasAnyMatches(List: Int[],) -> Bool {
for item in List {
if condition(item) {
return true
}
}
return false
}
func lessthanTen(number: Int) -> Bool {
return number < 10
}
var numbers = [20,19,12]
hasAnyMatches(numbers,0)">lessthanTen
最后还有三个没有理解透,等有ios 8 的环境再验证,好像是匿名函数的使用。
“numbers.map({ (number: Int) -> Int in let result = 3 * number return result })” “numbers.map({ number in 3 * number })” “sort([1,12,2]) { $0 > $1 }”
总结以上是内存溢出为你收集整理的swift数据类型全部内容,希望文章能够帮你解决swift数据类型所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)