TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Fun with Go Iterators

161 点作者 xnacly7 个月前

18 条评论

openasocket7 个月前
I work with Go a lot at my job, and I definitely prefer functional programming so I chafe at the language a bit. I was excited to incorporate iterators into our code. Unfortunately, I'm also working in an environment where we are memory constrained, so on our hot path we need to not allocate at all. I tried playing with the iterators a bit, and couldn't get it to produce something that didn't allocate. I got close, but as much as a tried I couldn't get below 1 allocation per loop (not per loop iteration, per loop). Which in any other setting would be fine, but not for our use case.
评论 #41801496 未加载
评论 #41803162 未加载
评论 #41803542 未加载
评论 #41819588 未加载
integrii7 个月前
Call me crazy, but I don't like any of this. Make more named functions. Keep your logic flat and explicit. I believe go wants you to code this way as well. Imagine the horrors this kind of function chaining creates. Actually, you don't have to. It's JavaScript.
评论 #41805577 未加载
评论 #41800732 未加载
评论 #41799400 未加载
评论 #41804499 未加载
评论 #41801131 未加载
评论 #41800248 未加载
pragma_x7 个月前
I absolutely love it when we can take advantage of Go&#x27;s type system and add additional traits and behaviors to existing types like this.<p>That said, I noticed something odd here. In order for a module like this to really shine, I think all these operations need to be functionally pure. Right now, some of these mutate the iterator&#x27;s `iter` method mid-stream, which is about as side-effect-ful as you can get.<p>```<p>func (i <i>Iterator[V]) Map(f func(V) V) </i>Iterator[V] {<p>cpy := i.iter<p>i.iter = func(yield func(V) bool) {<p><pre><code> for v := range cpy { v = f(v) if !yield(v) { return } } } return i </code></pre> } ```<p>Unless I&#x27;m misreading that, `i.iter` has new behavior after this call. A better way would be to return a new _iterator_ with the custom iter behavior instead.<p>``` func (i <i>Iterator[V]) Map(f func(V) V) </i>Iterator[V] {<p><pre><code> &#x2F;&#x2F; create a fresh iterator around a custom closure (NewIterator() is hypothetical in this case) return NewIterator(func(yield func(V) bool) { for v := range i.iter { v = f(v) if !yield(v) { return } } }) </code></pre> } ```
评论 #41802383 未加载
评论 #41800724 未加载
kubb7 个月前
Go people will do this and they&#x27;ll be content:<p><pre><code> a := []int{1,2,3,4} it := slices.All(a) it = slices.Reverse(it) it = slices.Map(it) it = slices.Filter(it, func(i int) bool { return i % 2 == 0 }) slices.ForEach(it, func(i int) { fmt.Println(i) }) </code></pre> I don&#x27;t judge the Go enjoyers, but I prefer writing TypeScript to Go which says it all.<p>Type-inferred arrow lambda for function arguments would go such a long way in making this code nicer... And not make compilation slower at all.<p><pre><code> it = slices.Filter(it, i =&gt; i % 2 == 0) slices.ForEach(it, i =&gt; fmt.Println(i))</code></pre>
评论 #41800546 未加载
评论 #41820518 未加载
评论 #41802335 未加载
评论 #41801224 未加载
评论 #41803422 未加载
gtramont7 个月前
Unfortunately the chain approach breaks down when if you need to `map` to a different type, for example. Go does not allow generic typed methods.
评论 #41799500 未加载
评论 #41798834 未加载
pdimitar7 个月前
Might be interesting to make a library that competes with <a href="https:&#x2F;&#x2F;github.com&#x2F;samber&#x2F;lo">https:&#x2F;&#x2F;github.com&#x2F;samber&#x2F;lo</a>?
评论 #41799475 未加载
评论 #41801521 未加载
评论 #41798723 未加载
评论 #41798798 未加载
indulona7 个月前
&gt; My issue with the go way of iterators is, you can’t chain them like you would in JavaScript<p>You are not supposed to chain them. This addiction to try and chain everything everywhere all the time is so freaking weird and has been for a very long time.<p>Not only you are completely losing grasp on what is going on and write code prone to errors, but you are making it unreadable for other people that will be maintaining or just reading your code who will come long after you are gone from the company or abandon your library.<p>This is where Go&#x27;s simplicity approach and splitting each action into its own for loop or block of code is a godsend for maintainability.
评论 #41805816 未加载
dilap7 个月前
The Reverse implementation seems off to me -- it runs through the iterator twice, once collecting into a slice, and then a second time filling the same slice in reverse. (So basically the first Collect call is only being used to find the length of the iterated sequence.) I&#x27;m not sure about Go conventions†, but I imagine it would be considered better form to only run through the iterator once, reversing the collected slice in-place via a series of swaps.<p>(† Are iterators even expected&#x2F;required to be reusable? If they are reusable, are they expected to be stable?)
评论 #41798929 未加载
评论 #41799258 未加载
评论 #41807706 未加载
mbrumlow7 个月前
&gt; My issue with the go way of iterators is, you can’t chain them like you would in JavaScrip<p>Because it’s not JavaScript, and that is a good thing.
评论 #41801239 未加载
评论 #41800245 未加载
binary1327 个月前
I’m trying to understand whether this is intended to make Go seem bad or whether it’s just coming across that way to me.
评论 #41800230 未加载
vyskocilm7 个月前
Shameless plug. I had experimented with Go iterators a while ago and did a <a href="https:&#x2F;&#x2F;github.com&#x2F;gomoni&#x2F;it">https:&#x2F;&#x2F;github.com&#x2F;gomoni&#x2F;it</a><p>It was updated to 1.23, so it is as idiomatic as I can get. And yes it has a map method between two types. Just a single simple trick used.
评论 #41803179 未加载
Savageman7 个月前
I like how the author uses a test to run arbitrary code, this is exactly how I do it too!
评论 #41811138 未加载
评论 #41807290 未加载
qudat7 个月前
We just released a go pkg that uses the new iter pkg. We were so excited by the interface in large part because of how simple iterators are to use.<p><a href="https:&#x2F;&#x2F;github.com&#x2F;picosh&#x2F;pubsub&#x2F;blob&#x2F;main&#x2F;pubsub.go#L18">https:&#x2F;&#x2F;github.com&#x2F;picosh&#x2F;pubsub&#x2F;blob&#x2F;main&#x2F;pubsub.go#L18</a><p>We have seen in other languages like JS and python the power of iterators and we are happy to see it in Go
tpoacher7 个月前
Since the article is making a not-so-subtle jab at python being unable to do chain operations, I&#x27;m making my annual rounds to point out that implementing simple, straightforward chain functionality in python is as simple as a two-line function definition:<p><pre><code> def chain( Accumulant, *Functions_list ): for f in Functions_list: Accumulant = f( Accumulant ) return Accumulant </code></pre> <a href="https:&#x2F;&#x2F;sr.ht&#x2F;~tpapastylianou&#x2F;chain-ops-python&#x2F;" rel="nofollow">https:&#x2F;&#x2F;sr.ht&#x2F;~tpapastylianou&#x2F;chain-ops-python&#x2F;</a>
skybrian7 个月前
I think it would be more idiomatic to use statements, not expressions. That is, it’s ok to use local variables for intermediate values in a pipeline.
评论 #41799517 未加载
icar7 个月前
This reminds me of RxJS (<a href="https:&#x2F;&#x2F;rxjs.dev&#x2F;" rel="nofollow">https:&#x2F;&#x2F;rxjs.dev&#x2F;</a>)
AndyKluger7 个月前
1. That&#x27;s a good looking Hugo theme!<p>2. Implicitly chain everything all the time!<p>In Factor, you might do it as:<p><pre><code> reverse [ sq ] [ even? ] map-filter [ . ] each </code></pre> Or with a little less optimizing:<p><pre><code> reverse [ sq ] map [ even? ] filter [ . ] each </code></pre> The least obvious thing is that the period is the pretty-print function.
Spivak7 个月前
It&#x27;s funny the author throws a dig at Python for its syntax that actively discourages this kind of code. Like… my guy you&#x27;re not taking the hint. Python makes things it doesn&#x27;t want you to do ugly as sin. It&#x27;s why lambda is so awkward and clunky.
评论 #41800986 未加载
评论 #41800627 未加载
评论 #41800606 未加载