初探swift语言的学习笔记一(基本数据类型)

作者:fengsh998
原文地址:http://blog.csdn.net/fengsh998/article/details/28258805
转载请注明出处
如果觉得文章对你有所帮助,请通过留言或关注微信公众帐号fengsh998来支持我,谢谢!

3号,端午刚过,回到公司第一个早上的两小时便贡献给了apple的ios 8 发布会,在看完后,感觉操作系统越来越离我们的生活更近了,更多的应用支持了人们的日常生活,健康,娱乐,旅游等领域,相信以后的生活也更加人工智能化,在发布会的最后,提到了swift的全新开发语言,据发布会上的介绍,更新安全,快捷,编码高效。因此也对此进行了第一阶段的初探与学习。

语言语法笔记:

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


还有一点有意思是变量或常量的命名名称,几呼支持各种字符,包知unicode字符。

  1. letconstvalue=70;let我爱你中国="我要写中国的操作系统";println(constvalue);println(我爱你中国);

上面代码写在一行时,需要用分隔号分开,如果不使用分号,可以使用换行符:

    letconstvalue=70
  1. let我爱你中国="我要写中国的操作系统"
  2. println(constvalue)
  3. println(我爱你中国)


运行后输出:

[html]
    70
  1. 我要写中国的操作系统




2.字符串串接及类型转换

大家可能用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似呼也嗅到了什么,也提提供了另一种参变量使用"\()" 操作符,其中括号中的还支持表达式操作。至于反斜扛操作嘛,就有点像大家在C/C++ 中的换行串接时,在行尾加上的\的含议差不多。看一下官方给出的例子:

“let apples = 3
let oranges = 5
let appleSummary = "I have\(apples)apples."
let fruitSummary = "I have\(apples + oranges)pieces of fruit.”

可能用文字表达不出\()的意思,其实就是参数变量 把上面四句翻译为oc 则为
NSInteger apples = 3;

NSInteger oranges = 5;

NSString *appleSummary = [NSString stringWithFormat:@"I have %d apples",apples];

经试验:

  1. letok=String(constvalue)+我爱你中国
  2. letokgood="字符串串接\(我爱你中国)"
  3. println(okgood)
输出为:

字符串串接我要写中国的操作系统


数据类型别名:

oc /c/c++都使用typedef 来约束新的类型别名

而swift 则使用typealias

typealias AudioSample = UInt16

字符串常量可以包括下面这些特殊字符:
空字符\0,反斜杠\,制表符\t,换行符\n,回车符\r,双引号\”和单引号\’
单字节Unicode字符,\xnn,其中nn是两个十六进制数
双字节Unicode字符,\unnnn,其中nnnn是四个十六进制数
四字节Unicode字符,\Unnnnnnnn,其中nnnnnnnn是八个十六进制数

    letwiseWords="\"Imaginationismoreimportantthanknowledge\"-Einstein"
  1. //"Imaginationismoreimportantthanknowledge"-Einstein
  2. letdollarSign="\x24"//$,UnicodescalarU+0024
  3. letblackHeart="\u2665"//♥,UnicodescalarU+2665
  4. letsparklingHeart="\U0001F496"//,UnicodescalarU+1F496

初始化一个空字串

    varemptyString=""//emptystringliteral
  1. varanotherEmptyString=String()//initializersyntax
同时可以使用isEmpty来判断字符串是否为空,这点真的很像pascal,delphi就是这样检测的。
    ifemptyString.isEmpty{
  1. println("Nothingtoseehere")
  2. }
在swift中字符串不是指针,而是实际的值,因此,在Swift中,一个String类型就是一个实际的值,当定义一个新的String,并且将之前的String值拷贝过来的时候,是实际创建了一个相等的新值,而不是仅仅像指针那样指向过去。同样在函数传递参数的时候,也是传递的实际值,并且创建了一个新的字符串, 后续的操作都不会改变原有的String字符串
单个字符的声明,像c/c++中使用 char,而swift中则使用:

    letyenSign:Character="¥"
通过for-in循环,可以遍历字符串中的每一个字符
    forcharacterin"Dog!"{
  1. println(character)
  2. }


字符串长度的统计,可以使用全局函数countElements可以计算一个字符串中字符的数量,这点与其它语言length好像有点不同。

    letunusualMenagerie="Koala,Snail,Penguin,Dromedary"
  1. println("unusualMenageriehas\(countElements(unusualMenagerie))characters")
  2. //prints"unusualMenageriehas40characters"
字符串与单个字符,可以使用+,+=操作将字符串和字符串接在一起。这点与其它语言稍先进一点。

字符串的比较使用 ==

    letquotation="We'realotalike,youandI."
  1. letsameQuotation="We'realotalike,youandI."
  2. ifquotation==sameQuotation{
  3. println("Thesetwostringsareconsideredequal")
  4. }
  5. //prints"Thesetwostringsareconsideredequal"
  6. //输出”Thesetwostringsareconsideredequal”

swift还保留了oc中的前后缀函数hasPrefix和hasSuffix

大小写字符串使用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属性

如例子:

    lettestUncode="Dog!狗"
  1. forcodeUnitintestUncode.utf8{
  2. print("\(codeUnit)")
  3. }
  4. print("\n")
  5. //6811110333231139151
  6. forcodeUnitintestUncode.utf16{
  7. //681111033329399
  8. forscalarintestUncode.unicodeScalars{
  9. print("\(scalar.value)")
  10. //681111033329399

在utf-8中,中文的"狗"占三个字节,而在utf-16 及标量(utf-32)中正好可以一个字节就装得下。


3.数组,字典

在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++吧。

    //数组使用
  1. //初始化时指定长度确定类型的
  2. varthreeDoubles=Double[](count:3,repeatedValue:0.0)
  3. println(threeDoubles)
  4. //不确定类型的
  5. varanotherThreeDoubles=Array(count:3,repeatedValue:2.5)
  6. println(anotherThreeDoubles)
  7. //varcomputerList=String[]()//创建一个空的数组
  8. varcomputerList:String[]=["lenovo","dell"]
  9. //varcomputerList=["lenovo","dell"]//与上等效
  10. if!computerList.isEmpty//判断是否为空数组
  11. {
  12. //数组长度
  13. println("数组共有\(computerList.count)元素.")
  14. println("元素分别为\(computerList.description)")//使用description访问
  15. //直接置空
  16. computerList=[]
  17. println("空数组\(computerList)")
  18. //动态追加元素
  19. computerList.append("sony")
  20. println("追加后为:\(computerList)")//真接访问
  21. computerList+="acer"
  22. println("追加后为:\(computerList.description)")
  23. //可以一次追加一个数组
  24. computerList+=["HP","samsung","Apple"]
  25. println("追加数组后为:\(computerList)")
  26. varitems=["Haier","东之"]
  27. computerList+=items
  28. println("追加数组后为:\(computerList)")
  29. //下标访问
  30. println("你访问索引3的元素\(computerList[3])")
  31. //使用下标进行修改元素值
  32. println("修改前为:\(computerList[2])")
  33. computerList[2]="SONY"
  34. println("修改后为:\(computerList[2])")
  35. //通过闭包访问一次修改多个值
  36. //注意[4..6]是半闭包即只包括改修4,5而不包括6
  37. //使用[4...6]是全闭包,可以修改4,5,6
  38. computerList[4...6]=["惠普","三星","a","b","c"]//元素超出部分会直接追加在末尾
  39. println("修改后为:\(computerList)")
  40. //插入元素
  41. computerList.insert("computer",atIndex:0)
  42. println("插入后为:\(computerList)")
  43. //通过索引进行删除元素
  44. letdel=computerList.removeAtIndex(0)
  45. println("删除的元素为:\(del)")
  46. //移除最后一个元素
  47. letdellast=computerList.removeLast()
  48. println("最后的元素为:\(dellast)")
  49. //遍历数组
  50. foritemincomputerList
  51. println(item)
  52. //如果需要每一个元素的整形的索引值,使用enumerate函数代替会更方便
  53. //enumerate函数对于每一个元素都会返回一个包含元素的索引和值的元组
  54. for(index,value)inenumerate(computerList)
  55. {
  56. println("Item\(index+1):\(value)")
  57. }

字典的使用

    //字典
  1. //Dictionary<KeyType,ValueType>唯一的限制就是KeyType必须是可哈希的(hashable)
  2. //varnamesOfIntegers=Dictionary<Int,String>()//创建空字典
  3. varairport:Dictionary<String,String>=["TYO":"Tokyo","DUB":"Dublin"]
  4. varairports=["TYO":"Tokyo","DUB":"Dublin"]
  5. //字典元素
  6. println("字典包函元素有\(airports.count)")
  7. //使用key添加value
  8. airports["LHR"]="London"
  9. println("添加元素后\(airports)")
  10. //使用key修改
  11. airports["LHR"]="LondonHeathrow"
  12. println("修改元素后\(airports)")
  13. /*updateValue(forKey:)方法如果键不存在则会设置它的值,如果键存在则会更新它的值,和下标不一样是
  14. updateValue(forKey:)方法如果更新时,会返回原来旧的值rThisenablesyouto可以使用这个来判断是否发生了
  15. updateValue(forKey:)方法返回一个和字典的值相同类型的可选值.例如,
  16. 如果字典的值的类型时String,则会返回String?或者叫“可选String“,
  17. 这个可选值包含一个如果值发生更新的旧值和如果值不存在的nil值。
  18. */
  19. ifletoldValue=airports.updateValue("DublinInternational",forKey:"DUB")
  20. println("TheoldvalueforDUBwas\(oldValue).")
  21. println("最新值\(airports)")
  22. //判空
  23. ifletairportName=airports["DUB"]
  24. println("Thenameoftheairportis\(airportName).")
  25. else
  26. println("Thatairportisnotintheairportsdictionary.")
  27. //字典移除
  28. airports["APL"]="AppleInternational"
  29. println("当前字典:\(airports)")
  30. airports["APL"]=nil
  31. println("移除后字典:\(airports)")
  32. //也可以使用removeValueForKey移除
  33. ifletremovedValue=airports.removeValueForKey("DUB")
  34. println("Theremovedairport'snameis\(removedValue).")
  35. println("TheairportsdictionarydoesnotcontainavalueforDUB.")
  36. //遍历字典
  37. for(airportCode,airportName)inairports
  38. println("\(airportCode):\(airportName)")
  39. //遍历key
  40. forairportCodeinairports.keys
  41. println("Airportcode:\(airportCode)")
  42. //遍历value
  43. forairportNameinairports.values
  44. println("Airportname:\(airportName)")
  45. //获取所有key转为数组
  46. letairportCodes=Array(airports.keys)
  47. println("所有keys为:\(airportCodes)")
  48. //获取所有value转为数组
  49. letairportNames=Array(airports.values)
  50. println("所有values为:\(airportNames)")


4.枚举类型

枚举在swift中可胃得到了很高的提升。不单单只简单的支持Int数据类型,还扩展了支持其它数据类型,一起来探究一下吧

基本语法:

    enumCompassPoint{
  1. caseNorth
  2. caseSouth
  3. caseEast
  4. caseWest
  5. }
每个case 为一个成员,但多个成员也可以写在一个case里,用逗号分隔
    enumPlanet{
  1. caseMercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune
  2. }


声明及使用
    //一旦指定了类型就可以使用.操作
  1. vardicection:CompassPoint
  2. dicection=.East
  3. vardirectionToHead=CompassPoint.West
  4. directionToHead=.South

与 switch配合使用

    vardirectionToHead=CompassPoint.West
  1. switchdirectionToHead{
  2. case.North:
  3. println("Lotsofplanetshaveanorth")
  4. case.South:
  5. println("Watchoutforpenguins")
  6. case.East:
  7. println("Wherethesunrises")
  8. case.West:
  9. println("Wheretheskiesareblue")
  10. //default://如果不需要各个都配置时,可以使用defult
  11. //println("nowhat");
  12. }

枚举的关联值支持

Swift的枚举类型可以由一些数据类型相关的组成,如果需要的话,这些数据类型可以是各不相同的。枚举的这种特性跟其它语言中的奇异集合
如:

    enumBarcode{
  1. caseUPCA(Int,Int,Int)
  2. caseQRCode(String)
  3. }

然后可以使用任何一种类型来创建如:

    varproductBarcode=Barcode.UPCA(8,85909_51226,3)
此示例创建一个名为productBarcode新的变量,并与相关联的元组值赋给它Barcode.UPCA的值(8,8590951226,3)。
也可以使用:

    productBarcode=.QRCode("ABCDEFGHIJKLMNOP")

不同的条码类型像以前一样可以使用一个switch语句来检查,但是这一次相关的值可以被提取作为switch语句的一部分。您提取每个相关值作为常数(let前缀)或变量(var前缀)不同的情况下,在switch语句的case代码内使用

    switchproductBarcode{
  1. case.UPCA(letnumberSystem,letidentifier,letcheck):
  2. println("UPC-Awithvalueof\(numberSystem),\(identifier),\(check).")
  3. case.QRCode(letproductCode):
  4. println("QRcodewithvalueof\(productCode).")
  5. 如果所有的枚举成员的关联值的提取为常数,或者当所有被提取为变量,为了简洁起见,可以放置一个var,或let标注在成员名称前

      caselet.UPCA(numberSystem,identifier,check):
    1. caselet.QRCode(productCode):
    2. }

    别外也可以有给成员设置指定值:

      enumASCIIControlCharacter:Character{
    1. caseTab="\t"//这里设置值要与<spanstyle="font-family:Arial,sans-serif;">Character类型相对应</span>
    2. caseLineFeed="\n"
    3. caseCarriageReturn="\r"
    4. }
      enumASCIIControlCharacter:Int{
    1. caseTab=10
    2. caseLineFeed=20
    3. caseCarriageReturn=30
    4. }
    同样还可以使枚举跟c/C++,java,pascal phyon等高级语言的效果一样。只需要设置第一个值后,后面的值会类推。

      enumPlanet:Int{
    1. 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()
    1. //earthsOrderis3
    另外,还提供了一个检查访问,fromRaw()
      letpossiblePlanet=Planet.fromRaw(7)
    1. //possiblePlanetisoftypePlanet?andequalsPlanet.Uranus

    使用枚举的fromRaw方法来试图找到一个特定的原始值枚举成员。这个例子识别Uranus的位置通过原始值为7:然而,并非所有可能的Int值都会找到一个匹配的星球。正因如此,该fromRaw方法返回一个可选的枚举成员。在上面的例子中,是possiblePlanet类型Planet?或“可选的Planet”。
    如果你试图找到一个Planet为9的位置,通过fromRaw返回可选的Planet值将是无:因此在配合switch时可以这样:

      letpositionToFind=9
    1. ifletsomePlanet=Planet.fromRaw(positionToFind){
    2. switchsomePlanet{
    3. case.Earth:
    4. println("Mostlyharmless")
    5. default:
    6. println("Notasafeplaceforhumans")
    7. }else{
    8. println("Thereisn'taplanetatposition\(positionToFind)")
    9. //prints"Thereisn'taplanetatposition9"


    5.条件表达式。

    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有点不同吧。

    经验证:多个条件也不需要用括号的。不过,如果你想要表达式正确,还是要按照运算优先级。

      varconstvalueB=200
    1. letconstvalue=70
    2. ifconstvalueB==0&&constvalue>60||constvalue!=20
    3. println("true")
    4. else
    5. println("false")
    6. }

    别外像:

      ifconstvalueB
    1. }
      constvalueB
    这样的条件,在swift中已经通不过了,对条件判断也更别严格了。

    再来看一下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中可以匹配一个数值范围

      letcount=3_000_000_000_000
    1. letcountedThings="starsintheMilkyWay"
    2. varnaturalCount:String
    3. switchcount{
    4. case0:
    5. naturalCount="no"
    6. case1...3:
    7. naturalCount="afew"
    8. case4...9:
    9. naturalCount="several"
    10. case10...99:
    11. naturalCount="tensof"
    12. case100...999:
    13. naturalCount="hundredsof"
    14. case1000...999_999:
    15. naturalCount="thousandsof"
    16. default:
    17. naturalCount="millionsandmillionsof"
    18. println("Thereare\(naturalCount)\(countedThings).")

    case中还可以直接测试元组是否符合相应的条件,_可以匹配任意值

      letsomePoint=(1,1)
    1. switchsomePoint{
    2. case(0,0):
    3. println("(0,0)isattheorigin")
    4. case(_,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> println("(\(somePoint.0),0)isonthex-axis")
    5. )
    6. case(-2...2,-2...2):
    7. )
    8. )
    9. //prints"(1,1)isinsidethebox"

    在case匹配的同时,可以将switch语句中的值绑定给一个特定的常量或者变量,以便在case的语句中使用。比如

      letanotherPoint=(2,0)
    1. switchanotherPoint{
    2. case(letx,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> println("onthex-axiswithanxvalueof\(x)")
    3. println("onthey-axiswithayvalueof\(y)")
    4. caselet(x,y):
    5. println("somewhereelseat(\(x),\(y))")
    6. //prints"onthex-axiswithanxvalueof2"



    思考:如果没有defalut:会是什么样的?有环境验证一下。

    验证后有几个有意思的地方:

    一,对成员具有完整性检测:如:

      enumCompassPoint:Int{
    1. vardirectionToHead=CompassPoint.West//预先指定为West
    2. switchdirectionToHead{
    3. case.North:
    4. println("Lotsofplanetshaveanorth")
    5. case.South:
    6. println("Watchoutforpenguins")
    7. case.East:
    8. println("Wherethesunrises")
    9. }
    这里编译期会报错,提示未找到West。
    可以通过以下两种方式进行修正:

      println("Wherethewest");
    1. }
      }

    别外还遇到一个告警问题:

    如果switch的条件声明在同一个函数内,这时会提示Switchcondition evaluates to a constant
    要去除这个,只需要将声明的变量放在函数外就可以

    vardirectionToHead :CompassPoint= .West



    6.循环

    for - in,for,while,do-while

    在for-in 中使用k/v数组,

    “let interestingNumbers = [
    "Prime": [2,3,7,11,13],
    "Fibonacci": [1,1,2,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.函数的语法

    “func greet(name: String,day: String) ->String{
    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[],condition: Int -> Bool) -> 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的对象和类(即面向对象编程)

    版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

    相关推荐


    软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘贴.待开发的功能:1.支持自动生成约束2.开发设置页面3.做一个浏览器插件,支持不需要下载整个工程,可即时操作当前蓝湖浏览页面4.支持Flutter语言模板生成5.支持更多平台,如Sketch等6.支持用户自定义语言模板
    现实生活中,我们听到的声音都是时间连续的,我们称为这种信号叫模拟信号。模拟信号需要进行数字化以后才能在计算机中使用。目前我们在计算机上进行音频播放都需要依赖于音频文件。那么音频文件如何生成的呢?音频文件的生成过程是将声音信息采样、量化和编码产生的数字信号的过程,我们人耳所能听到的声音频率范围为(20Hz~20KHz),因此音频文件格式的最大带宽是20KHZ。根据奈奎斯特的理论,音频文件的采样率一般在40~50KHZ之间。奈奎斯特采样定律,又称香农采样定律。...............
    前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿遍又亿遍,久久不能离开!看着小仙紫姐姐的蹦迪视频,除了一键三连还能做什么?突发奇想,能不能把舞蹈视频转成代码舞呢?说干就干,今天就手把手教大家如何把跳舞视频转成代码舞,跟着仙女姐姐一起蹦起来~视频来源:【紫颜】见过仙女蹦迪吗 【千盏】一、核心功能设计总体来说,我们需要分为以下几步完成:从B站上把小姐姐的视频下载下来对视频进行截取GIF,把截取的GIF通过ASCII Animator进行ASCII字符转换把转换的字符gif根据每
    【Android App】实战项目之仿抖音的短视频分享App(附源码和演示视频 超详细必看)
    前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至2022年4月底。我已经将这篇博客的内容写为论文,上传至arxiv:https://arxiv.org/pdf/2204.10160.pdf欢迎大家指出我论文中的问题,特别是语法与用词问题在github上,我也上传了完整的项目:https://github.com/Whiffe/Custom-ava-dataset_Custom-Spatio-Temporally-Action-Video-Dataset关于自定义ava数据集,也是后台
    因为我既对接过session、cookie,也对接过JWT,今年因为工作需要也对接了gtoken的2个版本,对这方面的理解还算深入。尤其是看到官方文档评论区又小伙伴表示看不懂,所以做了这期视频内容出来:视频在这里:本期内容对应B站的开源视频因为涉及的知识点比较多,视频内容比较长。如果你觉得看视频浪费时间,可以直接阅读源码:goframe v2版本集成gtokengoframe v1版本集成gtokengoframe v2版本集成jwtgoframe v2版本session登录官方调用示例文档jwt和sess
    【Android App】实战项目之仿微信的私信和群聊App(附源码和演示视频 超详细必看)
    用Android Studio的VideoView组件实现简单的本地视频播放器。本文将讲解如何使用Android视频播放器VideoView组件来播放本地视频和网络视频,实现起来还是比较简单的。VideoView组件的作用与ImageView类似,只是ImageView用于显示图片,VideoView用于播放视频。...
    采用MATLAB对正弦信号,语音信号进行生成、采样和内插恢复,利用MATLAB工具箱对混杂噪声的音频信号进行滤波
    随着移动互联网、云端存储等技术的快速发展,包含丰富信息的音频数据呈现几何级速率增长。这些海量数据在为人工分析带来困难的同时,也为音频认知、创新学习研究提供了数据基础。在本节中,我们通过构建生成模型来生成音频序列文件,从而进一步加深对序列数据处理问题的了解。
    基于yolov5+deepsort+slowfast算法的视频实时行为检测。1. yolov5实现目标检测,确定目标坐标 2. deepsort实现目标跟踪,持续标注目标坐标 3. slowfast实现动作识别,并给出置信率 4. 用框持续框住目标,并将动作类别以及置信度显示在框上
    数字电子钟设计本文主要完成数字电子钟的以下功能1、计时功能(24小时)2、秒表功能(一个按键实现开始暂停,另一个按键实现清零功能)3、闹钟功能(设置闹钟以及到时响10秒)4、校时功能5、其他功能(清零、加速、星期、八位数码管显示等)前排提示:前面几篇文章介绍过的内容就不详细介绍了,可以看我专栏的前几篇文章。PS.工程文件放在最后面总体设计本次设计主要是在前一篇文章 数字电子钟基本功能的实现 的基础上改编而成的,主要结构不变,分频器将50MHz分为较低的频率备用;dig_select
    1.进入官网下载OBS stdioOpen Broadcaster Software | OBS (obsproject.com)2.下载一个插件,拓展OBS的虚拟摄像头功能链接:OBS 虚拟摄像头插件.zip_免费高速下载|百度网盘-分享无限制 (baidu.com)提取码:6656--来自百度网盘超级会员V1的分享**注意**该插件必须下载但OBS的根目录(应该是自动匹配了的)3.打开OBS,选中虚拟摄像头选择启用在底部添加一段视频录制选择下面,进行录制.
    Meta公司在9月29日首次推出一款人工智能系统模型:Make-A-Video,可以从给定的文字提示生成短视频。基于**文本到图像生成技术的最新进展**,该技术旨在实现文本到视频的生成,可以仅用几个单词或几行文本生成异想天开、独一无二的视频,将无限的想象力带入生活
    音频信号叠加噪声及滤波一、前言二、信号分析及加噪三、滤波去噪四、总结一、前言之前一直对硬件上的内容比较关注,但是可能是因为硬件方面的东西可能真的是比较杂,而且需要渗透的东西太多了,所以学习进展比较缓慢。因为也很少有单纯的硬件学习研究,总是会伴随着各种理论需要硬件做支撑,所以还是想要慢慢接触理论学习。但是之前总找不到切入点,不知道从哪里开始,就一直拖着。最近稍微接触了一点信号处理,就用这个当作切入点,开始接触理论学习。二、信号分析及加噪信号处理选用了matlab做工具,选了一个最简单的语音信号处理方
    腾讯云 TRTC 实时音视频服务体验,从认识 TRTC 到 TRTC 的开发实践,Demo 演示& IM 服务搭建。
    音乐音频分类技术能够基于音乐内容为音乐添加类别标签,在音乐资源的高效组织、检索和推荐等相关方面的研究和应用具有重要意义。传统的音乐分类方法大量使用了人工设计的声学特征,特征的设计需要音乐领域的知识,不同分类任务的特征往往并不通用。深度学习的出现给更好地解决音乐分类问题提供了新的思路,本文对基于深度学习的音乐音频分类方法进行了研究。首先将音乐的音频信号转换成声谱作为统一表示,避免了手工选取特征存在的问题,然后基于一维卷积构建了一种音乐分类模型。
    C++知识精讲16 | 井字棋游戏(配资源+视频)【赋源码,双人对战】
    本文主要讲解如何在Java中,使用FFmpeg进行视频的帧读取,并最终合并成Gif动态图。
    在本篇博文中,我们谈及了 Swift 中 some、any 关键字以及主关联类型(primary associated types)的前世今生,并由浅及深用简明的示例向大家讲解了它们之间的奥秘玄机。