文档章节

Go 实现Linq的探索-2-延迟计算

yuweikang
 yuweikang
发布于 2017/02/11 15:50
字数 678
阅读 42
收藏 0

续上一篇的思路,解决延迟计算的问题。相关的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 *Query
var once sync.Once
func 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了

© 著作权归作者所有

yuweikang
粉丝 3
博文 11
码字总数 3349
作品 0
广州
程序员
私信 提问
短路逻辑和延迟加载

一、短路逻辑 短路逻辑(short-circuit logic)也叫懒惰求值(lazy evaluation),在我们熟知的布尔运算中有一个非常有趣的特性:只有在需要求值时才进行求值。举例来说,ConditionA() and ...

嗯哼9925
2017/11/09
0
0
linq学习圣经

linq是Language Integrated Query(LINQ,语言集成查询)属于net平台。通过LINQ,我们可以使用相同API操作不同的数据源。linq项目,包括linq威客系统交易系统开发,学生管理系统等。 。linq使...

crossmix
2015/11/25
58
0
LINQ简记(2):重要概念

为了能让初学者更快速地掌握,在系列文章中,我尽可能地避开理论讲解,一则对于入门者来说,过多的理论叙述反而会降低大家学习编程的兴趣,二则,官方文档的资料很详细,我说了也是废话。因此...

junwong
2012/04/18
76
0
从yield关键字看IEnumerable和Collection的区别

C#的yield关键字由来以久,如果我没有记错的话,应该是在C# 2.0中被引入的。相信大家此关键字的用法已经了然于胸,很多人也了解yield背后的“延迟赋值”机制。但是即使你知道这个机制,你也很...

长平狐
2012/09/04
146
0
.NET中数据访问方式(一):LINQ

语言集成查询(Language-Integrated Query),简称LINQ,.NET中的LINQ体系如下图所示: LINQ Hierarchy 在编程语言层次,LINQ对于不同的数据源提供了相同的查询语法,方便了程序员操作不同的...

雪飞鸿
2017/04/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 如果是个帅小伙你愿意和他出去吗

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 小小编辑推荐:《Ghost 》游戏《死亡搁浅》原声 《Ghost 》游戏(《死亡搁浅》原声) - Au/Ra / Alan Walker 手机党少年们想听歌,请使劲儿戳...

小小编辑
35分钟前
54
5
java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
今天
6
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
5
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
16
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
19
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部