在 if 语句中无法访问变量。这是语言设计的原因吗?

huangapple go评论83阅读模式
英文:

Variable not accessible inside if statement. Language design?

问题

所以我正在使用Go语言实现的Jade模板语言(参见https://github.com/go-floki/jade),并且遇到了一种有趣的语言“特性”。下面的代码按预期工作,为每个头像放置一个img元素。

each $headshot in $object.Headshots
    img.img-circle.headshot(src=$headshot)

然后,我想在第六个元素上更改图像源为预设图像。然而,当我运行这段代码时,我收到一个错误:

each $headshot, index in $cause.Headshots
    if index == 6
        img.img-circle.headshot(src="/public/images/ellipse.png")
    else
        img.img-circle.headshot(src=$headshot)

具体来说,报错为“未定义变量$headshot”。似乎$headshotif语句的作用域内不存在。这不是我第一次遇到这种实现中的行为,尝试解决问题非常令人沮丧。这让我想知道,语言可能有这样的工作方式的原因吗?

此外,有人能想到解决这种情况的方法吗?我能想到的最好的方法是在客户端使用JavaScript稍后进行更改。

英文:

So I'm working with an implementation of the Jade templating language for Go (see https://github.com/go-floki/jade) and I'm running into an interesting "feature" of the language. The code below works as expected, placing and img element for every headshot.

each $headshot in $object.Headshots
	img.img-circle.headshot(src=$headshot)

I then wanted to change it so on the sixth element the image source would be a preset image. However, when I run this code I get an error

each $headshot, index in $cause.Headshots
	if index == 6
		img.img-circle.headshot(src="/public/images/ellipse.png")
	else
		img.img-circle.headshot(src=$headshot)

Specifically undefined variable $headshot. It seems that $headshot does not exist within the scope of the if statement. This isn't the first time I've run into this behavior using this implementation and it's frustrating to try to work around. The trouble that it takes made me wonder, is there possibly a reason the language works this way?

Additionally, can anyone think of a way to work around the "feature" in this case? The best I can come up with is to change it later client-side with Javascript.

答案1

得分: 2

首先,Go的if代码块可以访问其封闭作用域中的变量。如果在你的示例中出现问题,那么可能是你的代码或所使用的库的实现错误。

接下来,让我们修复一些代码中的问题:

each $headshot, index in $cause.Headshots

顺序应该颠倒--索引应该在前面--并且让我们在使用$表示变量时保持一致:

each $i, $headshot in $cause.Headshots

搞清楚这一点后,这是一个完整的演示脚本:

templates/home.jade

html
    body
        each $i, $headshot in Cause.Headshots
            if $i == 0
                img.img-circle.headshot(src="/public/images/ellipse.png")
            else
                img.img-circle.headshot(src=$headshot)

demo.go

package main

import (
	"bufio"
	"os"

	"github.com/go-floki/jade"
)

func main() {
	w := bufio.NewWriter(os.Stdout)
	// compile templates
	templates, err := jade.CompileDir("./templates", jade.DefaultDirOptions, jade.Options{})
	if err != nil {
		panic(err)
	}

	// then render some template
	tpl := templates["home"]
	tpl.Execute(w, map[string]interface{}{
		"Cause": map[string]interface{}{
			"Headshots": []string{"one", "two"},
		},
	})
	w.Flush()
}

这段代码对我来说是有效的,输出结果是:

<html><body><img class="img-circle headshot" src="/public/images/ellipse.png" /><img class="img-circle headshot" src="two" /></body></html>

所以我的唯一结论是,在你的示例中可能还有其他问题。可能是库中的一个错误,但我首先会检查以下几点:

  • 在jade文件中是否混合使用了空格和制表符?这可能导致作用域混乱。
  • 上面我发布的示例是否也给你带来了错误?如果是这样的话,
    • 你是否使用了最新版本的Jade库?
    • 你的Go版本是否是最新的?
英文:

First off, Go's if blocks have access to variables in their enclosing scope. If this is failing in your example, it must be because of an implementation error either in your code or the library you are using.

Next, let's fix some problems in the posted code:

each $headshot, index in $cause.Headshots

The order should be reversed--index goes first--and let's be consistent with the use of $ to indicate variables:

each $i, $headshot in $cause.Headshots

With that cleared up, here is a full demo script:

templates/home.jade

html
    body
        each $i, $headshot in Cause.Headshots
            if $i == 0
                img.img-circle.headshot(src="/public/images/ellipse.png")
            else
                img.img-circle.headshot(src=$headshot)

demo.go

package main

import (
	"bufio"
	"os"

	"github.com/go-floki/jade"
)

func main() {
	w := bufio.NewWriter(os.Stdout)
	// compile templates
	templates, err := jade.CompileDir("./templates", jade.DefaultDirOptions, jade.Options{})
	if err != nil {
		panic(err)
	}

	// then render some template
	tpl := templates["home"]
	tpl.Execute(w, map[string]interface{}{
		"Cause": map[string]interface{}{
			"Headshots": []string{"one", "two"},
		},
	})
	w.Flush()
}

This code works for me, the output is:

<html><body><img class="img-circle headshot" src="/public/images/ellipse.png" /><img class="img-circle headshot" src="two" /></body></html>

So my only conclusion is that there must be something else going on in your example. It could be a bug in the library, but I would first check the following things:

  • is there a mixture of spaces and tabs in the jade file? This could cause scope confusion
  • does the example I posted above also give you an error? If so,
    • are you using the latest version of the Jade library?
    • is your Go version up to date?

huangapple
  • 本文由 发表于 2016年2月20日 08:31:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/35517552.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定