- 谈到函数式编程,恐怕最不能放过的就是闭包。闭包的定义总是不那么清晰,好像每种语言都有小许的差别。通常说的是可以捕获(访问)外部变量语句块,Swift 的闭包类似于 Objective-C 的 Block 或其他语言的 Lambda 表达式。所以闭包同 Lambda 基本上是同义词。
现在还没完, Swift 认为全局函数(有名字的,不能捕获外部变量)和嵌套函数(有名字,可捕获外部变量)也认为是特殊的闭包。闭包表达式(无名字的闭)才是真正意义上的闭包,它用最简洁的方式来书写一个函数。因此它尽了最大的可能的作了约定性的简化,例如参数与返回类型的推断,return 的省略,无参或只有一个参数的简化。
闭包的语法形式
{ (parameters) ->returntypein
statements
}
闭包中可用常量参数(let),变量参数(var), inout 参数,甚至是可变个数参数,但是不能用默认参数。说白了,闭包也就是无名函数的另一种写法。 Read More - 正好前段时间在发力理解函数式编程,学习 Swift 至今就想看看 Swift 对函数式编程的支持如何。从变量声明用 let, 以及函数参数的 let 和 var 都非常适合于函数式编程,它们对实例保护的很好。let 和 var 类型的函数参数保证了函数内部操作的是传入参数的深拷贝。
在 Objective-C 中要调用一个函数,除了通过对像为媒介,还能 perform 一个 selector, selector 其实也是定位函数的方式,这更像是反射。其实 C/C++ 的函数指针概念更不错,用于直接定位函数。
所以进一步,函数要成为第一等公民,它本身可以很容易的作为参数传入或作为返回值,即能构成高阶函数。这在 Swift 也是没问题的,我们可以定义函数类型的变量,例如:1func addTwoInts(a: Int, _ b: Int) -> Int { 2 return a + b 3} 4 5var addFunction: (Int, Int) -> Int = addTwoInts //addTwoInts 函数类型表示 (Int, Int) -> Int 6print(addFunction(1, 2)) 7let add = addTwoInts //自动推断出 add 函数的类型 8 9func foo() { 10 print(123) 11} 12let f:()->Void = foo
Read More - 由于 Swift 出自于名门 Apple,与 Objective-C 共同服务于 iOS/Mac OS X 平台,因而看得出它更像是脱胎于 Objective-C。现在来学习它的函数相关的知识,Swift 函数定义有些像 Scala,只是用 func 替代了 def, 返回类型的指定用的是
->而不是=, 格式如下:1func greet(name: String, day: String) -> String { 2 return "Hello \(name), today is \(day)" 3} 4 5greet("Bob", day: "Tuesday")
当然函数无参数就是空括号(不能省略空括号),无返回值的话就无需->指定类型了,比如 func greet() { print("Hello")},从形式上看不出是否有副作用(纯函数)
调用函数时和 Objective-C 是一样的,除第一个参数不需要指定形参名,其他参数必须指定形参名,并且顺序是要和函数定义时完全一样的。我们知道在 Objective-C 中一般约定把第一次参数包含在方法名中,如 Read More - 因为是本人学习 Swift 的笔记,是基于所掌握的其他语言来认识 Swift 的,所以并非详尽的 Swift ABC,也就显得凌乱不堪。不会自动转型,强型转型的方式是 String(变量值), 括号不是括住类型
1let number = 123 2let message = "total: " + a //这是错的,必须写成 “total: " + String(number), 直接常量的话 let message = “total:" + String(123)let 为常量, var 为变量, 类型的指定方式与 Scala 一样,如果不让它自动推断或无法推断时,这样指定类型Read More1var width: Double苹果的 Swift 语言第二版预计在今年底开源,届时还可在 Linux 下使用 Swift 语言。试想一下此语言用在服务端 Web 开发也该是个很好的方向,需要实现对 HTTP 协议的支持。
Swift 本身就可以做 Shell 脚本用,所以以 CGI 的方式运行是没问题的,没有第三方相关的框架,可以自己完全输出响应头和体。
我们可以把 Swift 集成到像 Apache 或 Nginx 的 Web 服务器中,要做的工作可能多些,应该要用到 C/C++ 来写 Swift 支持模块。想下我们用这种 URL http://localhost/service/customer.swift 来访问 swift 实现的后台页面。
或者也可以让 Swift 代码像 NodeJs 一样运行,自己启动 HTTP Server。幸运的是我们已经有了 Swifter 和 Taylor,再配之以纯 Swift 的模板实现 GRMustache, 简单开发不在话下。
一旦该语言流行开了,特别是能用在 Linux 平台下,总会有人去实现出对 HTTP 协议的支持,再配之以模板,让 Swift 像 PHP 一样在 Apache 中运行就不难了。 Read MoreJava 在运用面向方向编程时,依照 AspectJ 的语法自己书写 *.aj 文件可以得到尽可能大的控制能力。如果是一个 sbt 的项目,有一个 sbt-aspectj-plugin 插件可以帮上我们的忙。那么如何应用这个插件呢? 该插件首页面告诉我们要在project/plugins.sbt中加上下面这句话其他就是参考例子 runnable sample projects,然而这几个例子并非那么直白。所以还是自己做一个最简单的例子来体验 sbt 项目如何使用 AspectJ. Read More1addSbtPlugin("com.typesafe.sbt" % "sbt-aspectj" % "0.10.4")几年前整理过一篇 JUnit 4 如何正确测试异常,类似的问题:如何在 Scala 中测试异常呢?因 Scala 可以完全采用 JUnit 测试用例的风格,所以当然可以运用 Java 的三种方式来测试异常,即- try { 待测试代码; fail() } catch(某种异常) {断言}
- @Test(expected = Exception.class)
- @Rule
回到 Scala 中来,我并不那么情愿在 Scala 中使用 JUnit 的 @Test def testMethod() 这样的测试方法风格,而多少采用 BDD 或者叫更 DSL 的风格。
那看看我们 Scala 有些什么独到的异常测试方法
一: intercept Read More好的编程原则跟好的系统设计原则和技术实施原则有着密切的联系。下面的这些编程原则在过去的这些年里让我成为了一名优秀的程序员,我相信,这些原则对任何一个开发人员来说,都能让他的编程能力大幅度的提高,能让他开发出可维护性更强、缺陷更少的程序。
1. 不要自我重复(DRY - Don't repeat yourself)
这也许是在编程开发这最最基本的一个信条,就是要告诉你不要出现重复的代码。我们很多的编程结构之所以存在,就是为了帮助我们消除重复(例如,循环语句,函数,类,等等)。一旦程序里开始有重复现象的出现(例如很长的表达式、一大堆的语句,但都是为了表达相同的概念),你就需要对代码进行一次新的提炼,抽象。
2. 提炼原则(Abstraction Principle)
跟“不要自我重复原则”相关,这一原则是说“程序中任何一段具有功能性的代码在源代码文件中应该唯一的存在。”
3. 保持简单(KISS - Keep it simple, stupid!)
简单化(避免复杂)永远都应该是你的头等目标。简单的程序让你写起来容易,产生的bug更少,更容易维护修改。
4. 不要开发你目前用不到的功能(Avoid Creating a YAGNI - You aren't going to need it)
除非你真正需要用到它,否则不要轻易加上那些乱七八糟用不到的功能。 Read More在上一篇中写道 Java 泛型 -- 依据声明的变量类型自动推断,主要是说明了通过声明类型告知泛型方法具体类型,其后有个小结三种方式告知泛型类或泛型方法具体类型,在此重列如下:
一. 具体类型写在两尖括号中
1. List<String> list
2. new HashMap<String, String>
3. instance.<String>foo() //如方法 <T> T foo() { return (T) obj; }
二. 变量声明类型指示具体类型
1. List<String> list = new ArrayList<>() // 这个例子应该可以列在这里,List<String> 指示了具体类型是 String, 所以后只需要空 <>,JDK7 or later
2. String s = obj.foo() //比如方法是 <T> T foo() { return (T) obj; }, 由于前面的 String s 声明,所以不必写成 String s = instance.<String>foo()
三. 实参类型指示具体类型
1. instance.foo(String.class) //方法为 <T> T foo(Class<T> type) { return (T) obj; }, instance.foo(String.class) 返回的就是字符串值
2. instance.foo("abc") //方法为 <T> foo(T value) { return (T) obj; }, instance.foo("abc") 返回的就是字符串值 Read More