エラーメッセージGoウェブアプリケーションをリフレッシュしてパーソナライズされたダッシュボードが表示されるのを期待したところ、代わりに500エラーが発生することがあります。ログを確認すると、次のような特定の失敗が記録されています。
template: mytemplate:5:8: executing "mytemplate" at : can't evaluate field Username in type main.User
これは、テンプレートエンジンがアクセスできないデータ片を参照しようとしたために発生します。通常、原因は非公開(private)フィールドであるか、実行中に「ドット(.)」コンテキストがどのように遷移するかについての誤解にあります。
根本原因:エクスポートされたフィールドとエクスポートされていないフィールドGoの可視性ルールは単純です。大文字で始まるものは公開(エクスポート済み)、小文字で始まるものは非公開(未エクスポート)です。html/templateパッケージは、実行時にリフレクションを使用して構造体を読み取ります。しかし、リフレクションであってもGoのセキュリティをバイパスして非公開フィールドにアクセスすることはできません。
構造体が次のようになっていると仮定しましょう。
type User struct {
username string // 非公開
Email string // 公開
}
データを正しく渡したとしても、{{.username}}は失敗します。エンジンは非公開フィールドを、あたかも存在しないかのように扱います。
エラーの修正方法### 1. 構造体フィールドを大文字にする最も迅速な修正方法は、構造体の定義を変更することです。テンプレートで使用されるすべてのフィールド名が、大文字で始まっていることを確認してください。
type User struct {
Username string
Email string
}
テンプレートもそれに合わせて更新します:<p>こんにちは、{{.Username}}!</p>。この単純な変更で、これらのエラーの90%が解決します。
2. 「ドット」コンテキストをマスターする「ドット」(.)は現在のカーソルを表します。これは、{{range}}や{{with}}ブロックに入ると変化します。ブログ記事のリストを反復処理する場合、ドットはもはやトップレベルのデータではなく、現在処理している特定の記事を指すようになります。
{{range .Posts}}
<p>投稿者: {{.User.Username}}</p> <!-- これは多くの場合失敗します! -->
{{end}}
もしUserがPost構造体ではなくグローバルデータのプロパティである場合、テンプレートはクラッシュします。$を使用して、テンプレートに渡された元のデータルートに戻ることができます。
{{range .Posts}}
<li>執筆者: {{$.User.Username}}</li> <!-- これは動作します! -->
{{end}}
3. 大文字・小文字の区別を確認するGoは名前の大文字・小文字の区別に厳格です。構造体でUsernameと定義されているのに、HTMLテンプレートで{{.UserName}}('N'が大文字)を呼び出すと、評価は即座に失敗します。Goテンプレートにはフィールド名の「あいまい検索」機能はありません。
修正の検証小さな修正をテストするためだけにサーバー全体を再起動する必要はありません。テンプレートが正しく解析され実行されることを確認するために、クイックなスタンドアロンスクリプトを使用しましょう。
package main
import (
"html/template"
"os"
)
type User struct {
Username string
}
func main() {
const doc = `<p>こんにちは、{{.Username}}!</p>`
t := template.Must(template.New("test").Parse(doc))
// 実際のデータでテスト
err := t.Execute(os.Stdout, User{Username: "Alice"})
if err != nil {
panic(err)
}
}

