go ``` text/template: 范围遍历函数和整数 ```

2jcobegt  于 6个月前  发布在  Go
关注(0)|答案(8)|浏览(59)

提案详情
Rangefunc 更改是为了在自定义函数上添加对范围的支持。
text/html 模板标准库有一个范围操作符,其功能如 documented 所示。
模板库应该支持对函数的范围遍历。使用场景是希望在 SQL 行迭代器上返回一个 Rangefunc,然后将其传递给模板进行文本生成。
这是我们在 https://groups.google.com/g/golang-nuts/c/_lykyoQHmGc 小组中的讨论内容。

vnzz0bqm

vnzz0bqm1#

我认为我们需要定义一些语义,并且我认为可能存在一些未明确回答的问题。
首先,显然,有一对一变量和二元变量的迭代器。在 {{ range $x }} 中,如果 $xiter.Seq2[A, B] ,应该将 map[K]V 设置为什么值?为了一致性,我们将其设置为 ,这意味着它应该是 B 。另一方面,没有先验保证 iter.Seq2 的第二个参数确实一定是“类似值”的。
然后我们有 range 形式 {{ range $x, $y := $z }} ,即一个初始化一个或两个变量的 range 动作。可以假设使用两个变量与 iter.Seq 一起将是一个错误。使用一个变量与 iter.Seq2 (参见 also #65236)是否也应该是一个错误?
最后:如果在模板中调用函数或方法(无论是通过使用函数名作为操作,还是使用 call 函数),该函数可以选择返回类型为 error 的第二个参数:如果那个 error 不是 nil ,则中止模板执行并返回错误。这引发了如何处理 iter.Seq2[T, error] 的问题。
据我所知,关于迭代器的错误处理并不是完全清楚的。例如,如果你有一个从文件中读取行的迭代器,将每行解析为结构体,它可能会有两种失败方式:1. Read 可以失败,致命地中止迭代;2. 对单行的解析失败,允许以不同的方式处理该行的错误,但继续迭代。有些人建议对两者都使用 iter.Seq2[T, error] ,在这种情况下,范围遍历它的模板操作应该在发生错误时中止。另一方面,也许合理的做法是仍然从模板中处理该错误并继续迭代 - 只在“致命”错误上中止。我现在不确定我们在这一点上想要做出多少策略选择。
我可以想象的一种替代方案是说你可以以三种方式遍历 iter.Seq2 :1. {{ range $it }} ,它产生 T 并中止模板执行,如果第二个参数是错误;2. {{ range $x := $it }} ,它的行为相同(但设置 $x 而不是 . )和3. {{ range $x, $err := $it }} ,它在错误上不中止,允许模板随心所欲地处理它。这实际上将控制权交给了模板作者。
如果我们采纳这个建议,我们可能希望使 {{ range $it }} / {{ range $x := $it }} 在应用于 iter.Seq2[A, B] 时产生 A - 这与Map不一致,但与 iter.Seq2[T, error] 更一致。
至少这是我的想法。可能还有其他定义这些语义的方法。

9rygscc1

9rygscc12#

关于语义,似乎我们应该要求如果迭代器产生2个值,那么你必须使用{{range $x, $y := $f}}形式。

dluptydi

dluptydi3#

此建议已添加到建议项目中的活动列,并将在每周的建议审查会议上进行审查。
— rsc 建议审查组

uubf1zoe

uubf1zoe4#

允许对int进行遍历也是一致的。

5n0oy7gb

5n0oy7gb5#

这看起来没问题,但我们应该等待 #66056 来帮助实施。

fcg9iug3

fcg9iug36#

根据以上讨论,这个提案看起来像是很有可能被接受
— rsc(提案审查组)
该提案是允许在Go中对func和int进行范围遍历。

yb3bgrhw

yb3bgrhw7#

共识没有变化,所以接受。🎉
这个问题现在跟踪实施提案的工作。
— rsc提案审查组
提案是允许在Go中与func和int一样对范围进行操作。

vi4fp9gy

vi4fp9gy8#

https://go.dev/cl/596956提到了这个问题:text/template: support range-over-func

相关问题