Go 實現Linq的探索-2-延遲計算

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

續上一篇的思路,解決延遲計算的問題。相關的keyword很容易想到yield。
在C#中的延遲計算介紹可以參考一些文章,例如 “不能不說的C#特性-迭代器(下) yield以及流的延遲計算”
http://www.cnblogs.com/yuyijq/archive/2008/07/19/1246609.html
文章中提到

一、每次只返回一個元素的方法(閱讀者請跳到下文的第二部分)
從一個比較形式化的角度想,需要一個函數,每次調用去除列表最前面的元素,如果列表為空白,返回false。

type iterator func()(bool,interface{})

然後在使用的時候,for迴圈每次都會判斷擷取的bool傳回值為true的話,輸出結果。

    for ok, next := iter(); ok; ok, next = iter() {        fmt.Println(next)    }

定義一個包含上面提到的方法和列表的資料結構

type Query struct{    list []interface{}}

iter是iterator類型的,它的責任是每次只去除列表的頭一個元素,並對空列表的情況做判斷。

func (q *Query)GetIterator() iterator{    i:=0    return func() (bool,interface{}){        if i < len(q.list)  {            ret := q.list[i]            i++            return true,ret        }        return false,nil    }}

下面的方法用於添加資料

func (q *Query)generator(data interface{}){    q.list = append(q.list,data)}

第一次在Go上使用單例模式:once.Do

var m *Queryvar once sync.Oncefunc GeneratorInstance() *Query{    once.Do(func() {        m = &Query {}    })    return m}

下面開始檢查這種方法

func quips(name string) iterator{    GeneratorInstance().generator("Hi " + name + "!")    GeneratorInstance().generator("Hi" +        " good day , R u ok?")    GeneratorInstance().generator("en.. ok,good day")    return GeneratorInstance().GetIterator()}func main() {    iter := quips("Yk kang")    for ok, next := iter(); ok; ok, next = iter() {        fmt.Println(next)    }}

執行後會輸出:
Hi Yk kang2!
Hi good day , R u ok?
en.. ok,good day

二、與切片結合,讓筆記“探索一”裡面From().Select()支援延遲計算
其實質就是把From改造成像上文GetIterator的樣子;而Query不儲存list,list由From輸入,Query聲明了返回item的方法

type Iterator func()(item interface{},ok bool)type Query struct{    Iterate func() Iterator}func From(in interface{}) Query{    src := reflect.ValueOf(in)    len := src.Len()    return Query{        Iterate:func() Iterator{            i:=0            return func() (item interface{},ok bool){                ok = i < len                if ok{                    item = src.Index(i).Interface()                    i++                }                return            }        },    }}    next := From(userArr).Iterate()    for item,ok := next(); ok; item,ok = next() {        fmt.Println(item)    }

這樣便會正常輸出
{1 A 12}
{2 B 7}
{3 C 15}
而Select方法傳入的參數是selector func (interface{}) interface{},在方法體裡面從From返回的Query的Iterate方法得到item,ok,傳進selector裡面,因此Select方法是Query的

func (q Query) Select(selector func(interface{}) interface{}) Query {    return Query{        Iterate: func() Iterator {            next := q.Iterate()            return func() (item interface{}, ok bool) {                var it interface{}                it, ok = next()                if ok {                    item = selector(it)                }                return            }        },    }}//使用    t := From(userArr).Select(func(c interface{}) interface{}{        return  c.(User).Name    })    next := t.Iterate()    for item,ok := next(); ok; item,ok = next() {        fmt.Println(item)    }

按照這個函數鏈的邏輯,where方法也可以照搬Select了

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.