函数

func x(a:Int, b:Int)  {}   func x(a:Int, b:Int) -> Void {}  func x(a:Int, b:Int) ->(Int,Int) {}

外部参数名

func x(width a:Int,height b:Int) -> Int {}  func x(#a:Int,#b:Int) -> Int {}

//一般情况下可以不指定外部参数名,直接调用函数,但使用外部参数名,可以显著提高代码可读性:
func helloWithName(name: String, age: Int, location: String) {
println("Hello \(name). I live in \(location) too. When is your \(age + 1)th birthday?")
} helloWithName("Mr. Roboto", 5, "San Francisco") //但是在类 (或者结构、枚举) 中的时候,会自动分配外部参数名 (第一个除外)
class MyFunClass {
func helloWithName(name: String, age: Int, location: String) {
println("Hello \(name). I live in \(location) too. When is your \(age + 1)th birthday?")
}
// 可强制给第一个参数也加上外部参数名
func helloWithName2(#name: String, age: Int, location: String) {
println("Hello \(name). I live in \(location) too. When is your \(age + 1)th birthday?")
}
}
let myFunClass = MyFunClass()
myFunClass.helloWithName("Mr. Roboto", age: 5, location: "San Francisco")
myFunClass.helloWithName2(name: "Mr. Roboto", age: 5, location: "San Francisco") //不想要外部变量名,那么可以用 _ 来代替:
struct Celsius {
var temperatureInCelsius: Double
init(fromFahrenheit fahrenheit: Double) {
temperatureInCelsius = (fahrenheit - 32.0) / 1.8
}
init(fromKelvin kelvin: Double) {
temperatureInCelsius = kelvin - 273.15
}
init(_ celsius: Double) {
temperatureInCelsius = celsius
}
} let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
// boilingPointOfWater.temperatureInCelsius 是 100.0 let freezingPointOfWater = Celsius(fromKelvin: 273.15)
// freezingPointOfWater.temperatureInCelsius 是 0.0 let bodyTemperature = Celsius(37.0)
// bodyTemperature.temperatureInCelsius 是 37.0
//对外部参数名的娴熟应用可以极好的抽象初始化过程。

参数默认值

/// 有缺省值的参数一般放在参数列表末尾
func makeCoffee(type: String = "卡布奇诺")-> String{
return "制作一杯\(type)咖啡。"
}
let coffee1 = makeCoffee() //制作一杯卡布奇诺咖啡。
//外部参数名不可省
let coffee2 = makeCoffee(type :"拿铁") //制作一杯拿铁咖啡。 //可以用“_”申明不需要外部参数名
func drive(_ somebody:String = "我", _ car:String = "车"){
println("\(somebody)开着\(car)离开了")
}
drive() //我开着车离开了
drive("小李","一辆老爷车")

可变参数

// 如果有多个参数,可变参数必须放在参数列表末尾,所以也只能有一个可变参数
func sum(numbers: Double...)-> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total
} func sum(numbers:[Double])-> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total
} println("\(sum(100.0,20,30))")
println("\(sum([100.0,20,30]))")
println("\(sum(80,30))")
println("\(sum([80,30]))") //如果可变参数和缺省参数同时存在,缺省参数失效
func sumAddValue(_ addValue:String = "S", numbers: Int...) -> String {
var sum = ""
for number in numbers {
sum += number.description + addValue
}
return sum
}
sumAddValue(2, 2,4,5) //报错

常量与变量参数

// 形参默认声明为常量,无法在函数体中改变参数值。可以显示地声明为变量
/// 右对齐函数:
func alignRight(var string: String, num: Int, pad: Character) -> String {
let amountToPad = num - count(string)
if amountToPad < 1 {
return string
}
let padString = String(pad)
for _ in 1...amountToPad {
string = padString + string
}
return string
}
let originalString = "hello"
let paddedString = alignRight(originalString, 8, "-") // "---hello"

输入输出参数:值类型的引用传递 用inout 实现  调用是 参数前加&, 另参看运算符重载

func increment(inout value: Double, amount: Double = 1.0) {
value + =amount
} var value : Double =10.0
increment(&value)
println(value)
increment(&value,amount: 100.0)
println(value)

返回值

无返回值 func 函数名(参数列表){} 或 func 函数名 (参数列表) -> (){}/*()为空的元组*/ 或 func 函数名 ->Void (函数列表){}

多个返回值 可采用引用传递  或返回 元组

func position(t: Double,speed: (x: Int, y: Int)) -> (x:Int, y:Int) {
var posx:Int = speed.x * Int (t)
var posy:Int = speed.y * Int (t)
return (posx, posy)
} let move = position(60.0, (10,-5))
println("1小时后物体的位置坐标为(\(move.x),\(move.y))")
func componentsFromUrlString(urlString: String) -> (host: String?, path: String?) { let url = NSURL(string: urlString) return (url?.host, url?.path) } let urlComponents
= componentsFromUrlString("http://why/233;param?foo=1&baa=2#fragment") switch (urlComponents.host, urlComponents.path) { case let (.Some(host), .Some(path)): println("host \(host) and path \(path)") case let (.Some(host), .None): println("only host \(host)") case let (.None, .Some(path)): println("only path \(path)") case let (.None, .None): println("This is not a url!") }

泛型函数

func isEquals<T: Comparable> (a: T, b: T) ->bool { return (a == b) }
func isEquals<T> (a: T, b: T) -> T {...}
func isEquals<T, U> (a: T, b: U) -> T {... }

闭包

Swift中的仿函数(Functor)和Monad模型

函数式编程

维基百科中函数式编程的定义:  函数式编程是一种编程模型,他将计算机运算看做是数学中函数的计算,并且避免了状态以及变量的概念

无论多少进程在跑,因为保证了没有赋值操作,也就不会影响最终的运行结果,但也无法保存状态。

在其他编程模式中,用变量保存状态,因而并发编程,需要考虑”死锁“,需要担心一个线程的数据被另一个线程修改。而函数式编程本身是为了简化多核并行程序的设计。不依赖变量保存状态也就可以很放心地把工作分摊给多个线程,部署并发编程。

函数作为first class 是函数式编程的基础。努力用函数来表达所有的概念,完成所有的操作。

在面向对象编程中,我们把对象传来传去,那在函数式编程中,我们要做的是把函数传来传去。用函数来抽象,就是要用到高阶函数。

数学计算机科学中,高阶函数是至少满足下列一个条件的函数:

  • 接受一个或多个函数作为输入
  • 输出一个函数

f(x) = y ,无论在任何情况下相同的x传入只能返回相同的y,这就要求除了传入的x外,函数执行过程中的其他相关数据都不能发生变化。这样在实际操作中,意味着函数需要保持独立,需要保存环境。这些都需要用函数参数来保存,作为附属品一起传递。这是递归的模式。因而减少可变参数数量就变得非常重要,需要把树状递归转化为尾递归(currying),从而使对栈空间的占用处于常数级。

swift 中:

可以定义一个函数类型的常量或变量,并且可以赋值。

函数类型可以作为参数类型,也可以作为返回值类型。

函数是first class ,和其他基本数据类型一样,处于平等地位

//变量
//我们可以定义一个变量,这个变量的类型是函数类型:
func addTwoInts(a: Int, b: Int) -> Int {
return a + b
}
let anotherMathFunction = addTwoInts
anotherMathFunction(1,2) // 3 //参数 //函数既然是类型的一种,那么显然也是可以作为参数传递的: func addTwoInts2(a: Int, b: Int) -> Int {
return a + b
} func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) {
println("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts2, 3, 5) // 将参数2和参数3作为参数传给参数1的函数 //返回值
func stepForward(input: Int) -> Int {
return input + 1
} func stepBackward(input: Int) -> Int {
return input - 1
} func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
return backwards ? stepBackward : stepForward
} var currentValue = 3
let moveNearerToZero = chooseStepFunction(currentValue > 0) println("Counting to zero:")
while currentValue != 0 {
println("\(currentValue)... ")
currentValue = moveNearerToZero(currentValue)
}
println("zero!") // 3...
// 2...
// 1...
// zero! //别名 typealias typealias lotteryOutputHandler = (String, Int) -> String func luckyNumberForName(name: String, #lotteryHandler: lotteryOutputHandler) -> String {
let luckyNumber = Int(arc4random() % 100)
return lotteryHandler(name, luckyNumber)
} luckyNumberForName("Mr. Roboto"){
name, number in
return "\(name)'s' lucky number is \(number)"
}
// Mr. Roboto's lucky number is 33 // 嵌套
func chooseStepFunction2(backwards: Bool) -> (Int) -> Int {
func stepForward(input: Int) -> Int { return input + 1 }
func stepBackward(input: Int) -> Int { return input - 1 }
return backwards ? stepBackward : stepForward
}
var currentValue2 = -4
let moveNearerToZero2 = chooseStepFunction2(currentValue < 0) while currentValue2 != 0 {
println("\(currentValue2)... ")
currentValue2 = moveNearerToZero2(currentValue2)
} // 类似计算属性一样的嵌套函数写法
func getLogicValue(value:Int)->Bool{
// 类似计算属性一样的写法
var boolVale:Bool{
switch value{
case 0:
return false
default:
return true
}
}
println(boolVale) // 每次调用都会执行
return boolVale
} getLogicValue(11)
getLogicValue(0)

 闭包是一个代码块,它可以捕获其上下文中任意的变量和常量,延长其的生存周期以供自己使用,把函数以及这些变量包起来,而可以独立完成一个完整的功能。同时它如同普通数据类型的数据一样可以做参数,可以做返回值,参与了其他代码模块的构建。

 

var result: (Int, Int)-> Int
//闭包表达式,为自包含的匿名函数代码模块
// {(参数列表) ->返回值类型 in 语句组}
result = {(a:Int,b:Int)-> Int in return a-b} //由于swift的类型推断,上列式子可以简化
result = {a, b in return a - b} //省去参数和返回值类型
result = {a, b in a - b} //如果语句组只有一条语句 关键字 return 可省略
result = {$0 - $1} //使用参数名称缩写功能 省去 参数列表 //无参数的闭包
var result2 : () ->()
result2 = {println("hello")} //闭包作为参数时可能影响可读性,于是有了尾随闭包(闭包必须是最后一个参数)
//如果除了闭包没有其他参数了,甚至可以把小括号也去掉。 func repeat (count: Int, task: ()->()) {
for i in 0...count {
task ()
}
}
repeat(2, {
println("hello")
}
)
//改写为
repeat(2) {
println("hello")
} //闭包作为返回值
func caculate(#op:String)->(Int,Int)->Int
{
var result:(Int,Int)->Int;
switch(op){
case "+":result={(a:Int,b:Int)->Int in return a+b}
default:result={$0 > $1 ?$0-$1:$1-$0}
}
return result;
}
let f1 = caculate(op: "-")
println(f1(1,2))
println(f1(5,2)) let c1={$0 > $1 ?$0-$1:$1-$0}(6,2)
println(c1) let f4 :(Int,Int)->Int = {$0 > $1 ?$0-$1:$1-$0}
let yyyy = f4(2,2)

一个测试

typealias block = ()->()
class X{
func get(n:Int)->[block]{
var list = [block]()
for var i = 0; i < n; i++ {
list.append(
{
[weak self] in
println(self)
println(i)
}
)
}
return list
}
} class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
self.window = UIWindow(frame: Common.SIZE) var x:X? = X();
let list2 = x!.get(13) let queue = dispatch_queue_create("cn.itcast.queue", nil)
for ii in list2{
dispatch_async(queue, ii)
} println("ss:\(x)")
return true
}
// ....
} 输出:
/*
Ospst:iOopntailo(nba2lb(mba2lblm.aXl)l
.X)1
3
nil
13
nil
13
nil
13
nil
13
nil
13
nil
13
nil
13
nil
13
nil
13
nil
13
nil
13
nil
13
*/
/*
异步输出里的第一轮时x还在,与主线程的输出 重叠了。
在主线程执行完后 实例x即已释放,异步线程的后面几轮循环时,x实例已不存在,
但x 内的局部变量 i 依然可操作,
*/

修改版

typealias block = ()->()
class X{
func get(n:Int)->[block]{
var list = [block]()
var i = 0
for ; i < n; i++ {
list.append(
{
[weak self] in
println(self)
i++
println(i)
}
)
}
println(++i)
return list
}
} class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
self.window = UIWindow(frame: Common.SIZE) var x:X? = X();
let list2 = x!.get(13) let queue = dispatch_queue_create("cn.itcast.queue", nil)
for ii in list2{
dispatch_async(queue, ii)
} println("ss:\(x)")
return true
}
// ....
} 输出:
/*
14
Optionals(s:Optibonal(b22bmall.bX)
mall.X)
15
nil
16
nil
17
nil
18
nil
19
nil
20
nil
21
nil
22
nil
23
nil
24
nil
25
nil
26
nil
27
*/

闭包捕获的参数列表中, 实例的属性和方法的调用都会捕获实例变量,而局部变量的使用则仅捕获其自身。

但在测试2里, 外部方法内对局部变量 i 的修改 可以影响到闭包内的 i,同时闭包内对 i 的修改也会影响到其他闭包内 i 的值。这样实现了内外的一致性。

猜测是类似递归函数那样的参数捕获。即被捕获的变量加入了闭包函数的参数列表,那么对于值类型,为了保证一致性,传递的该是指针(inout)。

ARC

自动引用计数,swift中的内存管理方式,应用于引用类型(类,函数,闭包)

跟踪内存中的实例,每多一个变量或常量指向它时,它的引用计数加一,每少一个,引用计数减一,当计数为0时自动释放该实例所占内存空间。

强引用(strong reference type)

强引用(strong reference type) 会产生计数加一的效果

如果有多个实例的属性在互相引用,且都是强引用时,一旦形成闭环,则除非程序员主动介入解环,即便指向这些实例的变量,常量都已生命周期结束,这几个实例所占的内存也不会自动释放。

解决办法:

弱引用(weak reference), 无主引用(Unowned reference) 及 捕获列表(capture list)

弱引用与无主引用的区别

  弱引用声明为可选类型,无主引用声明为非可选类型,但二者都不会产生引用计数。因而被它们指向的实例是可能在中途自动释放的。

  区别在于: 弱引用指向的实例在被释放时会主动更新所有指向它的弱引用为nil(所以弱引用在性能上自然比无主引用要差一些), 这样弱引用被调用时,就可以先判别是非为nil,以避免程序奔溃。

    而无主引用则不能判别是否为nil,当被指向的实例已经不存在时,就会导致程序奔溃。

  所以要使用无主引用,即假如实例A的属性指向实例B,则要求B实例在整个A实例存活期间,始终存在,即B一定要死在A的后面。

  所以一般情况下,会选择使用弱引用

捕获列表是弱引用与无助引用在闭包中的运用。

class WeatherReport:NSObject{
lazy var reports:()->String = {
[weak self] in
if let strongSelf = self{
return strongSelf.description
}
else{
return ""
}
}
} // 写在playground 时 a= nil 并没有把a所占空间释放掉
// 在app 中执行正常
var a:UIView? = UIView()
println(a!.description)
//<UIView: 0x7fbfeae0daa0; frame = (0 0; 0 0); layer = <CALayer: 0x7fbfeae0dbb0>> var b = UIView()
let closure:(Int)->() = {
[weak a,unowned b] (num:Int) in
if let stronga = a{
println( stronga.description + b.description)
}
else{
println( num.description)
}
} closure(1)
//<UIView: 0x7fbfeae0daa0; frame = (0 0; 0 0);
//layer = <CALayer: 0x7fbfeae0dbb0>><UIView: 0x7fbfeac5fd60;
//frame = (0 0; 0 0); layer = <CALayer: 0x7fbfeac5fe70>>
a = nil
closure(3)
//3

柯里化 (currying)

//柯里化背后的基本想法是,函数可以局部应用,意思是一些参数值可以在函数调用之前被指定或者绑定。这个部分函数的调用会返回一个新的函数。

//显示柯里化
func curryUnnamed2(first a:Int)->((Int)->Int){
func curryInner(b:Int)->Int{
return a + b
}
return curryInner
} // 隐式柯里化
func curryUnnamed(first a:Int)(second b:Int)->Int{
return a + b
}
let result = curryUnnamed(first: 1)(second: 2) // 3 let f1 = curryUnnamed(first: 1) //(second b:Int)->Int
let result2 = f1(second: 2)
/// 普通形式
func salary(name:String,base:Int,to:Int)->Bool{
println("\(name)收到工资:\(base) 加班费:\(to)")
return true
} /// 柯里化形式
func salary(name:String)(base:Int)(to:Int)->Bool{
println("\(name)收到工资:\(base) 加班费:\(to)")
return true
} typealias paySalaryTypeCurried = Int->Int->Bool
func success(type:String,salary:Int->Int->Bool){
if type == "砖工"{
salary(200)(250)
}
else{
salary(100)(100)
}
}
func fail(reason:String){
println("跳了")
} func begSalaryByFormean(who:String,success:(String, paySalaryTypeCurried)->(),fail:(String)->()){
if who == "良心企业"{
success("砖工", salary("老张"))
success("瓦工", salary("老李"))
}
else{
fail("")
}
}
begSalaryByFormean("良心企业", success, fail)
class MyHelloWorldClass {

    func helloWithName(name: String) -> String {
return "hello, \(name)"
}
} let helloWithNameFunc = MyHelloWorldClass.helloWithName
//let helloWithNameFunc:MyHelloWorldClass->String->String = MyHelloWorldClass.helloWithName
let myHelloWorldClassInstance = MyHelloWorldClass()
helloWithNameFunc(myHelloWorldClassInstance)("Mr. Roboto")

swift中的反射(2.0后有较大改变,待修改)

http://www.cocoachina.com/industry/20140623/8923.html

protocol Reflectable {
func getMirror() -> Mirror
}
protocol Mirror {
var value: Any { get }
var valueType: Any.Type { get }
var objectIdentifier: ObjectIdentifier? { get }
var count: Int { get }
subscript (i: Int) -> (String, Mirror) { get }
var summary: String { get }
var quickLookObject: QuickLookObject? { get }
var disposition: MirrorDisposition { get }
}
// metatype-type –> type.Type
// type-as-value –> type.self
// 其中 metatype-type 出现在代码中需要类型的地方, type-as-value 出现在代码中需要值、变量的地方。
var a :Int.Type
var b:UIImage.Type
var c:UITableViewDelegate.Type UITableView().registerClass(UITableViewCell.self, forCellReuseIdentifier: "reuseCell") //反射信息用 Mirror 类型表示,类型协议是 Reflectable
protocol Reflectable {
func getMirror() -> Mirror
}
protocol Mirror {
var value: Any { get }
var valueType: Any.Type { get }
var objectIdentifier: ObjectIdentifier? { get }
var count: Int { get }
subscript (i: Int) -> (String, Mirror) { get }
var summary: String { get }
var quickLookObject: QuickLookObject? { get }
var disposition: MirrorDisposition { get }
}
Mirror 协议相关字段:

1.value 相当于变量的 as Any 操作

2.valueType 获得变量类型

3.objectIdentifier 相当于一个 UInt 作用未知,可能是 metadata 表用到

4.count 子项目个数(可以是类、结构体的成员变量,也可以是字典,数组的数据)

5.subscript(Int) 访问子项目, 和子项目的名字

6.summary 相当于 description

7.quickLookObject 是一个枚举,这个在 WWDC 有讲到,就是 Playground 代码右边栏的显示内容,比如常见类型,颜色,视图都可以

8.disposition 表示变量类型的性质,基础类型 or 结构 or 类 or 枚举 or 索引对象 or … 如下

enum MirrorDisposition {
case Struct // 结构体
case Class // 类
case Enum // 枚举
case Tuple // 元组
case Aggregate // 基础类型
case IndexContainer // 索引对象
case KeyContainer // 键-值对象
case MembershipContainer // 未知
case Container // 未知
case Optional // Type?
var hashValue: Int { get }
}
通过函数 func reflect<T>(x: T) -> Mirror 可以获得反射对象 Mirror 。它定义在 Any 上,所有类型均可用。

实际操作
 
.valueType 处理
Any.Type 是所有类型的元类型,所以 .valueType 属性表示类型。实际使用的时候还真是有点诡异:
  1. let mir = reflect(someVal)
  2. swift mir.valueType {
  3. case _ as String.Type:
  4. println("type = string")
  5. case _ as Range<Int>.Type:
  6. println("type = range of int")
  7. case _ as Dictionary<Int, Int>.Type:
  8. println("type = dict of int")
  9. case _ as Point.Type:
  10. println("type = a point struct")
  11. default:
  12. println("unkown type")
  13. }
 
或者使用 is 判断:
  1. if mir is String.Type {
  2. println("!!!type => String")
  3. }
is String 判断变量是否是 String 类型,而 is String.Type 这里用来判断类型是否是 String 类型。
 
subscript(Int) 处理
实测发现直接用 mir[0] 访问偶尔会出错,也许是 beta 的原因。
  1. for r in 0..mir.count {
  2. let (name, subref) = mir[r]
  3. prtln("name: \(name)")
  4. // visit sub Mirror here
  5. }
通过上面的方法,基本上可以遍历大部分结构。
 
不同类型的处理
 
Struct 结构体、 Class 类
  • .count 为字段个数。
  • subscript(Int) 返回 (字段名,字段值反射 Mirror) 元组
  • summary 为 mangled name
Tuple 元组
  • .count 为元组子元素个数
  • subscript(Int) 的 name 为 “.0”, “.1” …
Aggregate 基础类型
包括数字、字符串(含 NSString)、函数、部分 Foundation 类型、 MetaType 。
 
很奇怪一点是测试发现枚举也被反射为基础类型。怀疑是没实现完。
  • .count 为 0
 
IndexContainer 索引对象
包括 Array<T>, T[], NSArray 等。可以通过 subscript 访问。
  • .count 为元组子元素个数
  • subscript(Int) 的 name 为 “[0]”, “[1]” …
 
KeyContainer 键-值对象
包括 Dictionary<T, U>、NSDictionary
  • .count 为元组子元素个数
  • subscript(Int) 的 name 为 “[0]”, “[1]” … 实际访问是 (name, (reflect(key), reflect(val)))
 
Optional Type?
只包括 Type?,不包括 Type!。
  • .count 为 0 或者 1 (对应 nil 和有值的情况)
  • subscript(Int) , name 为 “Some”
 
其他
Enum 枚举 看起来是未使用
MembershipContainer // 未知
Container // 未知
 
示例代码
let aclass: AnyClass! = NSClassFromString("UIControl")
aclass.isSubclassOfClass(UIView) //true
let superfunc = aclass.superclass //()->AnyClass?
superfunc() //UIView
aclass.superclass() //UIView let aUIControl = UIControl(frame: CGRectZero)
let super1: AnyClass? = aUIControl.superclass //UIView
let super2: AnyClass? = super1?.superclass() //UIResponder
let super3: AnyClass? = super2?.superclass() //NSObject
let super4: AnyClass? = super3?.superclass() //nil aUIControl.isKindOfClass(UIView) //true println(aclass.description()) //UIControl
println(UIView.description()) //UIView
println(UIView.self) //UIView
println(Int.self) //Swift.Int

swift 学习(二)基础知识 (函数,闭包,ARC,柯里化,反射)的更多相关文章

  1. Java函数式编程:二、高阶函数,闭包,函数组合以及柯里化

    承接上文:Java函数式编程:一.函数式接口,lambda表达式和方法引用 这次来聊聊函数式编程中其他的几个比较重要的概念和技术,从而使得我们能更深刻的掌握Java中的函数式编程. 本篇博客主要聊聊以 ...

  2. JavaScript 闭包&基于闭包实现柯里化和bind

    闭包: 1 函数内声明了一个函数,并且将这个函数内部的函数返回到全局 2 将这个返回到全局的函数内中的函数存储到全局变量中 3 内部的函数调用了外部函数中的局部变量 闭包简述: 有权访问另一个函数局部 ...

  3. Scala基础:闭包、柯里化、隐式转换和隐式参数

    闭包,和js中的闭包一样,返回值依赖于声明在函数外部的一个或多个变量,那么这个函数就是闭包函数. val i: Int = 20 //函数func的方法体中使用了在func外部定义的变量 那func就 ...

  4. 浅析 JavaScript 中的 函数 uncurrying 反柯里化

    柯里化 柯里化又称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数函数,直至返回最后结果. 因此柯里化的过程是 ...

  5. 【 js 基础 】【 源码学习 】柯里化和箭头函数

    最近在看 redux 的源码,代码结构很简单,主要就是6个文件,其中 index.js 负责将剩余5个文件中定义的方法 export 出来,其他5个文件各自负责一个方法的实现. 大部分代码比较简单,很 ...

  6. JS的闭包、高阶函数、柯里化

    本文原链接:https://cloud.tencent.com/developer/article/1326958 https://cloud.tencent.com/developer/articl ...

  7. js高阶函数应用—函数柯里化和反柯里化(二)

    第上一篇文章中我们介绍了函数柯里化,顺带提到了偏函数,接下来我们继续话题,进入今天的主题-函数的反柯里化. 在上一篇文章中柯里化函数你可能需要去敲许多代码,理解很多代码逻辑,不过这一节我们讨论的反科里 ...

  8. 前端进击的巨人(五):学会函数柯里化(curry)

    柯里化(Curring, 以逻辑学家Haskell Curry命名) 写在开头 柯里化理解的基础来源于我们前几篇文章构建的知识,如果还未能掌握闭包,建议回阅前文. 代码例子会用到 apply/call ...

  9. 精读JavaScript模式(六),Memoization模式与函数柯里化的应用

    假期就这么结束了!十天假就有三天在路上,真的难受!想想假期除了看了两场电影貌似也没做什么深刻印象的事情.流浪地球,特效还是很赞,不过对于感情的描写还是逃不掉拖沓和尴尬的通病,对于国产科幻还是抱有支持的 ...

随机推荐

  1. JMS学习(六)-ActiveMQ的高可用性实现

    原文地址:http://www.cnblogs.com/hapjin/p/5663024.html 一,ActiveMQ高可用性的架构 ActiveMQ的高可用性架构是基于Master/Slave 模 ...

  2. I/O工作机制

    I/O问题是任何编程语言都无法回避的问题,可以说I/O是整个人机交互的核心问题,因为I/O是机器获取和交换信息的主要渠道.java的I/O操作类在包java.io下,大概有将近80个类,这些类大概可以 ...

  3. oracle基本用法

    作为企业版的后台数据支撑,就首先要掌握oracle的使用方法!!! 注册用户之前,需要使用system管理员来进行注册功能!!! 1.首先创建新用户 2.这样就能使创建的新用户能够登陆吗?不,还需要分 ...

  4. Symbol ES6 新增的一种值类型数据,表示一种绝不重复的值

    let s1 = Symbol(33); let s2 = Symbol(33); alert(typeof(s1)); //数据类型判断 // alert(s1.toString()); //可把一 ...

  5. android中按电源键锁屏然后解锁导致Activity调用onDestory以及如何防止锁屏

    今天在android项目中按电源键锁屏,然后解锁,发现子Activity关闭了,回到了主页,这个问题困扰了我很久,最后打log发现,在按电源键的时候,调用了子Activity的onDestroy()方 ...

  6. WPF:自动执行"机器人"程序若干注意事项

    企业应用中,经常会遇到一些需要定时自动执行的程序来完成某些功能,比如:自动定时从第三方web service取回数据.定时对历史数据进行清理.定时向ftp上传业务数据... 这类程序,我习惯称为“机器 ...

  7. addShutdownHook的用法

    addShutdownHook作为一个正常关闭Java程序的途径,其实是非常有用的. 有JDK文档可知,当程序正常退出,或者为响应用户中断而终止虚拟机的时候,就会调用里面的线程,来作最后的退出处理. ...

  8. 【转】加快网站访问速度——Yslow极限优化

    Yslow是一套雅虎的网页评分系统,详细的列出了各项影响网页载入速度的参数,这里不做多说. 我之前就一直参考Yslow做博客优化,经过长时间的学习也算是有所收获,小博的YslowV2分数达到了94分( ...

  9. ViewModelBase && ObservableObject

    ViewModelBase && ObservableObject 在Mvvm中,ViewModel和Model都需要具有通知界面更新数据的能力,这都要借助于WPF中的 INotify ...

  10. Theano3.1-练习之初步介绍

    来自 http://deeplearning.net/tutorial/,虽然比较老了,不过觉得想系统的学习theano,所以需要从python--numpy--theano的顺序学习.这里的资料都很 ...