scala-Future和Promise

递归函数

每当函数内部,可以调用其他函数。如果一个函数在内部调整用我本身,这个函数就是递归函数。

'''创建一个递归,将传入的参数不断的除以2,到0为止'''
def calc(n):
    print(n)
    if int(n/2) > 0 :
        return calc( int(n/2) )

calc(10)

出口结果也:

10
5
2
1

递归特性:

  1. 非得有一个明确的结条件

  2. 历次上更深一层递归时,问题规模相比上次递归都应持有回落

  3. 递归效率不愈,递归层次过多会招致栈溢出(在计算机被,函数调用是透过储藏室(stack)这种数量结构实现的,每当进入一个函数调用,栈就会加相同层栈帧,每当函数返回,栈就会见减弱一交汇栈帧。由于栈的分寸不是最的,所以,递归调用的次数过多,会促成栈溢出)

堆放栈扫盲http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html

率先说明并跟异步,阻塞与非阻塞的题目:
Asynchronous vs. Synchronous

python 函数

A method call is considered synchronous if the caller cannot make
progress until the method returns a value or throws an exception. On
the other hand, an asynchronous call allows the caller to progress
after a finite number of steps, and the completion of the method may
be signalled via some additional mechanism (it might be a registered
callback, a Future, or a message).
A synchronous API may use blocking to implement synchrony, but this is
not a necessity. A very CPU intensive task might give a similar
behavior as blocking. In general, it is preferred to use asynchronous
APIs, as they guarantee that the system is able to progress.

特性

  1. 减去代码重复
  2. 假若程序变得而扩大
  3. 倘若程序变得爱维护

Future

一个Future会见怀有一个价值,虽然这价当明天有时间点才可用。

  1. 若是算未就,那么是Future就是非到位。
  2. 万一算好(得到结果或者很),这个Future纵使完了了。

Future只能于派一不好,一旦Future被得矣一个价或很,它的结果不能够修改。

object Main extends App {
  import scala.concurrent.ExecutionContext.Implicits.global
  import scala.concurrent.Future
  val f:Future[Int]=Future{
    Thread.sleep(100)//模拟某个耗时操作 比如网络请求
    println("haha")
    10
  }
  Thread.sleep(1000)
}
  //haha

返回值

一旦想得函数的行结果,就可以就此return语句把结果返回

注意:

函数在履行过程中如果碰到return语句,就会告一段落执行并返结果,so
也得以解啊 return 语词代表在函数的收
假使不当函数中指定return,那这个函数的返回值为None 。

合方法取得结果

通过Await.result足齐获取结果,或者逾期或者深。Await.ready伺机计算好,不归结果。

val r=Await.result(f,Duration.Inf) //Await.result(f,1 seconds)

函数的参数

形参也得叫做形参变量,只有当为调用时才分配内存单元,在调用了时,即自由所分配的内存单元。所以形参只能在函数内部生效。函数调用结束返回主调用函数后虽未克还用该形参变量。

实参可以是常量、变量、表达式、函数等,无论实参是何种类型的计量,在进展函数调用时,它们还须来确定的值,以便把这些值传送给形参。因此应事先用赋值,输入等办法使参数获得确定值

葡京娱乐注册 1

scala中的FuturePromise都是勿死的实施,既可以经过回调函数获取结果,但是也可经阻塞的点子串行获取结果。

非固定参数

一旦您的函数中连无是死确定用户会传出多少只参数,那么即使可以应用非固定参数。

'''非固定参数'''
def test01(x,y,*args):
    print(x,y)
    print(args)

test01('李白','艳艳',12,3,4)

输出结果为:

李白 艳艳
(12, 3, 4)

消专注的凡,当用了*args的时节,会发现传入的参数全部于在了一个元组中。那么一旦想使操作的口舌不过待按照元组的操作方法操作即可。

非固定参数除了可转移成元组以外,还可以以盛传的多少易成字典,需要以**kwargs,代码如下:

def stu_register(name,age,*args,**kwargs): # *kwargs 会把多传入的参数变成一个dict形式
    print(name,age,args,kwargs)

stu_register("Alex",22)
#输出
#Alex 22 () {}#后面这个{}就是kwargs,只是因为没传值,所以为空

stu_register("Jack",32,"CN","Python",sex="Male",province="ShanDong")
#输出
# Jack 32 ('CN', 'Python') {'province': 'ShanDong', 'sex': 'Male'}

Promise

除却通过Future.apply创建Future靶,还可使Promise.future。如果说Future凡一个只是读之,值还并未算的挤占位符。那么Promise便是一个不过写的,单次指派的容器。Promise好经调用success代表Future打响做到,failure方抛来很。或者又抽象的complete

object Main extends App {
  import scala.concurrent.ExecutionContext.Implicits.global
  import scala.concurrent.{Future,Promise}
//  import scala.concurrent.duration._
  val p=Promise[Int]
  val f=p.future
  val producer=Future{
    p complete Try{
      100
    }
  }
  val consumer=Future{
    f onComplete{
      case Success(i)=>println(i)
      case Failure(e)=>e.printStackTrace()
    }
  }
  Thread.sleep(1000)
}

默认参数

率先,先来拘禁下的代码:

def stu_register(name,age,country,course):
    print('------注册学生信息--------')
    print('学员姓名:',name)
    print('学员年龄:',age)
    print('学员国籍:',country)
    print('学员选择课程:',course)

stu_register('小明',19,'中国','web前端')
stu_register('小红',20,'中国','linux')
stu_register('李白',25,'中国','python')

在上头的实例中,每一个学员登记的国籍都是炎黄,而在网上的有网站面临,如果无去手动设置,都默看中国,这就是是透过默认参数实现之。

如下,把country变成默认参数,

def stu_register(name,age,course,country='中国')

那么这重登记学员的早晚要国籍是神州就算可不待进行国籍的传参,而是使用默认的参数。

异步方法获得结果

目的获取结果,而不是决定实施进程。
scala提供了onSuccess对等回调函数。其签名也:def onComplete[U](f: Try[T] => U)(implicit executor: ExecutionContext): Unit

f.onComplete({
    case Success(i) => println(i)
    case Failure(e) => e.printStackTrace()
  })

上述代码应用偏函数形式,或者:

  f.onComplete(result=>result match {
    case Success(i)=>println(i)
    case Failure(e)=>e.printStackTrace()
  })

尚可以挂号多独回调:

f.onComplete(result=>result match {
    case Success(i)=>println(i)
  })
f.onComplete(result=>result match {
    case Success(i)=>println(i+20)
  })

横流:多个回调函数之间并无包实施各个

着重参数

正规情况下,给函数传参数要依顺序,不思量按部就班梯次葡京娱乐注册就可以用要参数,只待点名参数号称即可,但切记一个求就是是,关键参数必须在位置参数后。

# 使用关键字参数
stu_register(name='小明',country='中国',age=19,course='linux')
'''关键字参数必须放在位置参数之后'''
stu_register('小红',country='中国',age=19,course='linux')

Non-blocking vs. Blocking

函数的开创

python中开创函数,需要运用__def__重在字,后面写函数的名字,然后是展示参列表,大体如下:

def 函数名(形参列表):
    函数体......
    return 返回值

中显示参列表和 return返回值并无是必的。

We talk about blocking if the delay of one thread can indefinitely
delay some of the other threads. A good example is a resource which
can be used exclusively by one thread using mutual exclusion. If a
thread holds on to the resource indefinitely (for example accidentally
running an infinite loop) other threads waiting on the resource can
not progress. In contrast, non-blocking means that no thread is able
to indefinitely delay others.
Non-blocking operations are preferred to blocking ones, as the overall
progress of the system is not trivially guaranteed when it contains
blocking operations.

有的变量和全局变量

当python中,函数外部声明的变量我们叫全局变量,在函数内部宣称的变量是部分变量。

全局变量可以当变量声明后的任何职务使,而部分变量只会当函数内部采用。

'''全局变量和局部变量'''
name = '李白' # 函数外部声明 ,称之为全局变量

def test():
    age = 20 # 函数内部声明,称之为局部变量
    print(age) # 局部变量只能够在函数内部使用
    print(name) # 全局变量可以在函数内部使用
test()
# print(age) 在函数外部没有办法使用局部变量

__tip:函数内部宣称全局变量__

一旦想如果在函数内部宣称全局变量,需要采用global关键字

def test():
    global test
    test = '李白斗酒诗百篇'
test()
print(test) # 李白斗酒诗百篇

透过global关键字就算能在函数内部创立全局变量,但是这种写法是无引进应用的,有或导致变量污染。

再有一些得小心,看下的代码:

name = '艳艳'

def test():
    # 在函数中更改全局变量name的值
    name = 'hello,world'
    print(name) # hello,world
test()
print(name) # 艳艳

上述代码中,在函数中针对全局变量进行了改变,并且打印更改后的变量,那么打印的结果是更改的结果,但是于函数的外围再打印在函数中改的全局变量,发现结果连不曾被移,因为于函数中改变全局变量,那么更改了后底值作用域仅留在函数当中。

那哪些当函数中对全局变量更改而在函数外部调用结果吧转后的值也?同样可采用global关键字来实现。

name = '艳艳'

def test():
    global name
    # 在函数中更改全局变量name的值
    name = 'hello,world'
    print(name) # hello,world
test()
print(name) # hello,world

如上文献摘自akka文档,一个道之所以给名同步方法,是盖直到该方法返回某值或者抛来老,该法的调用者才能够收获结果(make progress)。如果一个异步调用需要经额外的机制(比如callback,Future,message)。如果一个线程的延导致了别一个(一些)线程的缓,那么漫长出现了不通(blocking)。一个例证就是是一个资源被一个线程所独占,那么其它线程需要等待这个线程释放资源才会继续执行。

定义

函数是负以同组报告句之集通过一个名(函数号称)封装起来,要想实行之函数,只需要调整用该函数名叫即可。

函数的应用

怀念使调用函数程序,需要盖函数叫加括号的形式展开调用,而括号内可以传参数,而括号内之参数我们称为__实参列表__,传入的实参会通过形参传递进函数,在函数内部就好使用了。如下:

def add(x,y):
    return x + y

# 调用函数
add(10,20)

要小心的是,python中的实参列表每一个参数之前用逗号分割,而向add()括号内之10,20这么的参数我们叫位置参数(positional
argument)。

这就是说得专注的凡,在python中,函数的实参的个数必须与形参的个数一样,实参个数多于形参或者少于形参都会报错。