for以及range使用的限制问题

99 views
Skip to first unread message

Earthson Lu

unread,
Mar 10, 2013, 7:41:45 AM3/10/13
to golang...@googlegroups.com
感觉Golang中的for range有些奇怪。主要是for range和一般的for expr表现不一致。这似乎是一种内置的处理?

比如

for i := 0; k, v := range mymap; i++ {
    do_something
}

这样的代码不能工作,这多少令人有些失望。实际上不得不在循环外面声明一些没必要的变量?这种感觉并不好,有其实只有i这样的一个迭代变量。

~~~~~~~~~~~~~

另外一个问题是,函数的多返回 

我不知道Golang里面函数的返回有没有一种类型(就像python中的元组)。

比如这样,完全不能工作

for n, err := fmt.Fscanf(fptf, "%d%d", &a, &b) {
    do_somethins_with_a_b
}

实际上我不得不这么干

for func(n int, err error) bool {
        return n != 0 && err == nil
    }(fmt.Fscanf(fptf, "%d%d", &a, &b) {
    do_some_thing_with_a_b
}

这看起来并不好。

大家有什么看法没?怎么才能构造出可以实践的迭代方案。 
--

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Perfection is achieved 
not when there is nothing more to add
 but when there is nothing left to take away

曹贤

unread,
Mar 13, 2013, 2:52:06 AM3/13/13
to golang...@googlegroups.com
for i := 0; k, v := range mymap; i++ {
    do_something
}
for i:=0;k,v:= range mymap{
    i++
  do_something
}


for n, err := fmt.Fscanf(fptf, "%d%d", &a, &b) {
    do_somethins_with_a_b
}

for n,err:= fmt.Fscanf(fptf, "%d%d", &a, &b); err!=nil {
       do_somethins_with_a_b
}

这样应该是可以的 同学 慢慢体会吧go非常灵活的


--
--
官网: http://golang-china.org/
IRC: irc.freenode.net #golang-china
@golangchina
 
---
您收到此邮件是因为您订阅了 Google 网上论坛的“Golang-China”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到 golang-china...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/groups/opt_out。
 
 

Earthson Lu

unread,
Mar 14, 2013, 3:45:14 AM3/14/13
to golang...@googlegroups.com
我这里不行啊。。

 20     mymap := make(map[int]int)
 21     mymap[1] = 1
 22     mymap[2] = 3
 23     for i := 0; k, v := range mymap {
 24         i++
 25         fmt.Println(i, k, v)
 26     }

错误信息:

 # command-line-arguments
./test.go:23: syntax error: unexpected range
./test.go:27: syntax error: unexpected }

shell returned 2


 14     a, b := 0, 0
 15     for n, err := fmt.Fscanf(file, "%d%d", &a, &b); err == nil && n != 0 {
 16         fmt.Println(a, b)
 17     }


# command-line-arguments
./test.go:15: syntax error: unexpected semicolon or newline before {
./test.go:27: syntax error: unexpected }


按照The Go Programming Language Specification的范式, for似乎没有两个";"的格式。

RangeClause = Expression [ "," Expression ] ( "=" | ":=" ) "range" Expression .
~~~~~~~~~~~~
难道新版本的golang里面有支持?

确实,文件那个版本主要是因为InitStmt和PostStmt不能合在一块儿,写两遍虽然可以,不过就有些太长了。

如果go有你说的双分号的for,那确实是非常不错的说:)


2013/3/13 曹贤 <cjmx...@gmail.com>

Earthson Lu

unread,
Mar 14, 2013, 4:08:08 AM3/14/13
to golang...@googlegroups.com
其实复杂的判断放在Block的内部也没什么事,有break和continue之类的可以使用。

不过有些简单的判断,个人还是倾向放在循环的条件上。这个问题其实主要是Go的多返回导致的,因为它不能直接作为表达式来操作。而range本身看起来就像是个特例。

另外,Go在很多地方确实都非常保守。比如整数和浮点数不支持自动转换。实际上int代入浮点操作都需要float64来手动转。这导致长而难以阅读的数学表达式。当然,我说的转换是运行期的,不是编译期。

鄙人学习Go还不是很多,有些地方有错还请指正:)


2013/3/14 Earthson Lu <earth...@gmail.com>

Earthson Lu

unread,
Mar 14, 2013, 4:32:34 AM3/14/13
to golang...@googlegroups.com
int到float64的转换,其实可以在编译期自动完成。既然编译器可以发现错误,自然可以自动添加这种转换。

实际上,如果我使用常数的话,比如1/3.3,这是可以工作的。但是为什么a/3.3就不行呢?(a是int类型的)


2013/3/14 Earthson Lu <earth...@gmail.com>

Oling Cat

unread,
Mar 14, 2013, 8:48:50 AM3/14/13
to Golang-China
ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .
这不就是么?你那两个Condition后面都需要分号的,因为没有PostStmt



2013/3/14 Earthson Lu <earth...@gmail.com>

曹贤

unread,
Mar 14, 2013, 9:34:28 AM3/14/13
to golang...@googlegroups.com
不好意思我写的是错误的

Earthson Lu

unread,
Mar 14, 2013, 9:37:42 AM3/14/13
to golang...@googlegroups.com
囧,前面邮件写错了。二楼回给我的是单分号的for。

两个condition后面都要有分号我当然知道,因为二楼回的只有一个分号,所以我就试了下。然后贴出范式,确定一个分号是不行的说。

另外,添上分号自然是错的,因为我要遍历文件的每一行(而不是死循环)。在C里面可以这样写的:

while(scanf("%d", &a) != EOF) { 
    //do_something 
}

当然,这种写法在函数多返回之后就完蛋了。 替代方案是使用匿名函数,不过感觉不是特别好(还不如把判断写在循环里面)

其实我也不是纠结for的形式,只是比较在意函数多返回无法无法直接进行逻辑判断(不像Python)。这样感觉比较受限。我只是期望迭代可以更方便一些。


2013/3/14 Oling Cat <olin...@gmail.com>

Liigo Zhuang

unread,
Mar 25, 2013, 11:17:10 AM3/25/13
to golang...@googlegroups.com

range就是个半残,不支持用户自定义类型。

--

steve wang

unread,
Mar 25, 2013, 11:38:22 AM3/25/13
to golang...@googlegroups.com
我觉得不支持挺好,别搞得C++那样复杂。

Razor

unread,
Apr 18, 2013, 12:21:10 PM4/18/13
to golang...@googlegroups.com
我倒觉得不支持是个缺陷,造成了语法上的不一致性.比如我在一个包中定义
type MyRange []int
这样当你在另一个包中使用MyRange类型的时候不看定义的话,根本无法确定此类型是否可用range来遍历.
我觉得可以参照C#的IEnumerable的实现,让range也针对接口,而不是有限的几个类型和其变种.

在 2013年3月25日星期一UTC+8下午11时38分22秒,steve wang写道:

steve wang

unread,
Apr 18, 2013, 12:56:26 PM4/18/13
to golang...@googlegroups.com

我认为要使用一个包的导出接口(包括数据、类型和方法等),不看它们的定义貌似不应该吧。
range要是可以支持自定义类型,map大概也需要提供一个枚举器了,这样会把go语言搞得太复杂。假如以后会用某种方式来支持,我想也不会是以增加复杂性为代价。
Reply all
Reply to author
Forward
0 new messages