BOO入门/将函数当作物件与多执行绪

维基教科书,自由的教学读本
跳到导航 跳到搜索

BOO入门 > 将函数当作物件与多执行绪 (上一章:例外 下一章:Generators)


译注:boo 里的函数宣告好以后,就是一个物件了,你可以试着在 booish 里使用 dir( your_function ) 看看。

将函数当作物件时,有三个有用的方法可用:

  1. function.Invoke(<arguments>) as <return type>
  2. function.BeginInvoke(<arguments>) as IAsyncResult
  3. function.EndInvoke(IAsyncResult) as <return type>

.Invoke 等同于呼叫函数本身,就像是:function()。 .BeginInvoke 会启始一个单独的执行绪来执行这个函数。 .EndInvoke 会完成之前启始的函数并回传适当的型别。

// .Invoke 的範例
def Nothing(x):
    return x

i = 5
print 5 == Nothing(i)
print i == Nothing.Invoke(i)
print i == Nothing.Invoke.Invoke(i)
// 譯註:原文使用 assert,這裡我改用 print 直接印出 boolean 值。使用 assert 時,後兩行執行時會出現 ERROR: 'bool' cannot be used in a boolean context.

你可以看到,.Invoke 就与呼叫函数一样,甚至你还可以继续把 .Invoke() 当作物件使用。

这里有个 .BeginInvoke 的好例子:

//  .BeginInvoke 開始多執行緒
import System
import System.Threading

class FibonacciCalculator:
    def constructor():
        _alpha, _beta = 0, 1
        _stopped = true
    
    def Calculate():
        _stopped = false
        while not _stopped:
            Thread.Sleep(200)
            _alpha, _beta = _beta, _alpha + _beta
            print _beta
    
    def Start():
        _result = Calculate.BeginInvoke()
    
    def Stop():
        _stopped = true
        Calculate.EndInvoke(_result)

    _result as IAsyncResult
    
    _alpha as ulong
    _beta as ulong
    
    _stopped as bool

fib = FibonacciCalculator()
fib.Start()
prompt("按下 Enter 停止...\n")
fib.Stop()

输出将会在每 200 毫秒(millisecond) 产生一个 Fibonacci数列,在超过 2^64 的时候,会发生一个溢出错误。(为什么是 200 毫秒?因为使用了 Thread.Sleep(200) ) 重要的是,当你按下 Enter 的时候,这个执行绪将会停止。

练习[编辑]

  1. 试着呼叫 .BeginInvoke 两次看看,看看结果会如何?
  2. 跟 C# 比较看看,谁的方法比较方便?