浅谈Swift语法

Apple 在2014年6月的WWDC发布了一款新型的开发语言,许多美国程序员的价值观貌似和我们很大的不同,在发布的时候我们可以听到,场下的欢呼声是接连不断的。如果换作我们,特别是像有Objective-C开发经验的开发者,是否也能和他们一样,乐观积极的面对这一新型的,剔除C的语言呢?当然,这对很多不愿意使用或者反感Objective-C的开发者们,提供了一条途径进行iOS本地应用开发。


好了,言归正传,这里,我从一个iOS开发人员的角度,来浅谈一下Swift的语法!


首先,一个很简单的用法,输出函数:

println("Hello, world")

从这段代码里,我们可以发现这个函数名好像在Java里见过:

System.out.println("Hello world");

根据Apple在其书籍《The Swift Programming Language》中的描述,这句代码实际上已经是可以做为一个独立的程序来运行[1],在调用这个函数时,并不需要写多余的代码,这实际上反应了该语言的简洁性。同时,我还发现,这句代码后没有我们常见的 “ ; " 分号,这是学某个语言的节奏吗?好像是python还是哪个?


在变量声明这一块,我们使用了var来作为变量声明符,比如说:

var myVariable = 42
myVariable = 50

我们发现,这里的用法和Javascript比较相似,使用var来定义变量,并不声明变量类型。它的格式就是 var 变量名。


对于常量声明,Swift使用类似F#的let来声明,比如说:

let myConstant = 42



除了类似于Javascript的变量声明外,这里也提供了类似于Jscript和C#的语法,为变量指定类型。同时这里也和一些函数式语言如F#有点相像。说点题外话,尽管我早知道Javascript和JScript是不同的,但是实际的不同是我在使用Unity脚本时才发现的,Unity脚本支持Javascript,但实际上,起初很多语法我并没有见过,直到我在MSDN上找到了JScript的文档和教程,才发现这实际上是JScript。Unity文档中很多都是指向MSDN的。

这里显示了如何指定变量类型:

let explicitDouble: Double = 70


如果我们要转换变量的类型,必须显式的转换,如:

let label = "The width is "
let width = 94
let widthLabel = label + String(width)

转换的方式就是:目标类型(变量)。这种转换方式我是不赞同的,如果能像Java一样自动转换那就更好了。


相信很多学过C以及类C语言的朋友对%d不陌生吧,我常常拿它用来把整形(int)塞进字符串里,这里同样有个长得像的方法:

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

这个方法就是"字符串\(要转换的变量如int)字符串"。 有点儿类似类C语言里的 XXXX("字符串%d字符串", 要转换的int)。


现在我们要看一下数组了,数组的基本使用代码如下:

var shoppingList = ["catfish", "water", "tulips", "blue paint"]
shoppingList[1] = "bottle of water"
 
var occupations = [
    "Malcolm": "Captain",
    "Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations”
第一个和第二个用法大同小异与许多语言,对于Objective-C来说,有趣的是第三个和第四个,我们发现了,无需使用NSArray类,Swift的数组,本身就支持key-value数组。

同时,我们也能建立字典类型,这个用法是很多语言都存在的:

let emptyDictionary = Dictionary<String, Float>()


流程控制语句是变更的比较大的,褒义的讲,for-in还有if-else的语法更加自然了:

let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores {
    if score > 50 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
teamScore

实际上,在Objective-C的语法中,只是多了个括号。如果不了解这个语法的可以评论写下或者Google一下。其实猜应该也能猜出来吧。值得一提的是,因为抛弃了C,所以不要想着0为false其余true的用法了,if只能判断boolean。



这里有一个奇怪的用法,我见识短浅,实在没见过。

var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {
    greeting = "Hello, \(name)"
}
各位注意到没,第一个变量optionalName的类型是String,但与此前不同的是,String后面多了个?,这是干嘛的呢。根据文档上说,加了?,就代表这个变量的值是可选的。啥?可选的?什么意思??我想了很久很久,得出了很多错误结论,最后一句话总结,你在其它语言能否int i=NULL?不能吧?懂了吧。我这里说的只是新特性,其它的都不是。



嗯,终于看到函数了,函数也比较灵(qi)活(pa),比如说实现了多个返回值。


先从比较简单的函数谈起:

func greet(name: String, day: String) -> String {
    return "Hello \(name), today is \(day)."
}
greet("Bob", "Tuesday")

这个函数各位应该能猜到是怎么回事吧?这是一个简单的2个参数1个返回值的函数。name和day是参数名,他们:后面就是参数的类型了,这个在JScript中有。返回值类型当然就是->后面的String了。



灵(qi)活(pa)的部分来了,我以前好多次见过有人问,为啥不能返回多个值啊?我们常用一些类(class)来解决这个问题,但现在容易了,这样就行:

func getGasPrices() -> (Double, Double, Double) {
    return (3.59, 3.69, 3.79)
}
getGasPrices()
其实看了这个很多人可能和我一样想问,哪里来的变量可以同时接受3个值?事实上,这里的3个dobule返回值是没意义的,演示多返回值而已。


这里有个例子:

func count(string: String) -> (vowels: Int, consonants: Int, others: Int) {
    var vowels = 0, consonants = 0, others = 0
    for character in string {
        switch String(character).lowercaseString {
        case "a", "e", "i", "o", "u":
            ++vowels
        case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
        "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
            ++consonants
        default:
            ++others
        }
    }
    return (vowels, consonants, others)
}

let total = count("some arbitrary string!")
println("\(total.vowels) vowels and \(total.consonants) consonants")

看到没,这里的3个int返回值都有了返回名称,用常量total储存通过.来使用。


还有就是,函数定义中能嵌套个子函数定义,比如说func a{....func b{.....}}:

func returnFifteen() -> Int {
    var y = 10
    func add() {
        y += 5
    }
    add()
    return y
}
returnFifteen()

这个应该很好理解。


很多没有函数编程经验的人看了书,有疑问,说啥是functions are a first-claas type? 其实这个很好理解,就是“函数是一等的”,也可以说是“一等函数”。在很多类C语言中,你如果想把函数做为参数传递出去,要用函数指针或者代理来间接传递吧?但是在Javascript中,函数也是一个类型,这种函数被称为“一等函数”,既然是个类型,就能像普通的变量一样愉快的传来传去。 Swift中的函数就是这样的。


在Swift中,函数能做为另一个函数的返回值。等等,有点绕口了,这样说吧,一个函数能返回另一个函数,不饶了吧大笑

func makeIncrementer() -> (Int -> Int) {
    func addOne(number: Int) -> Int {
        return 1 + number
    }
    return addOne
}
var increment = makeIncrementer()
increment(7)


既然能当返回值传,当然也能当参数传:抓狂

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, 7, 12]
hasAnyMatches(numbers, lessThanTen)



另外,也支持闭包,如果里面只有一句话,那么就返回那句话的左值

numbers.map({
    (number: Int) -> Int in
    let result = 3 * number
    return result
    })l



好了,开始谈谈类了,类其实就是长这样,没有我们期待的Swift Style:

class Shape {
    var numberOfSides = 0
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}

其实结合了前面谈的,其余跟Java差不多,init为构造。

class Square: NamedShape {
    var sideLength: Double
    
    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 4
    }
    
    func area() ->  Double {
        return sideLength * sideLength
    }
    
    override func simpleDescription() -> String {
        return "A square with sides of length \(sideLength)."
    }
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()


好了,有变化的来了,以下代码演示了类属性的getter和setter,这个语法明显有C#的影子,但是(看下面)

class EquilateralTriangle: NamedShape {
    var sideLength: Double = 0.0
    
    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 3
    }
    
    var perimeter: Double {
    get {
        return 3.0 * sideLength
    }
    set {
        sideLength = newValue / 3.0
    }
}

var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
triangle.perimeter
triangle.perimeter = 9.9
triangle.sideLength

其实在set里面还有didset,willset。。。。。。。。真实非(sang)常(xin)灵(bing)活(kuang)!


大部分谈完了,下一章接着讲,嗯,标题加上(1)。总结一下,这个语言我不感觉适合初学者,因为过于灵活,大量的结合了函数编程的语法,我感觉难以控制和统一代码质量。还有本人才疏学浅,这篇文章分析的错误率低于50%就谢天谢地了,请各路神仙,各位老师指教!!!!微笑





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值