Golang从session读取结构体时变量处理问题

Golang从session读取结构体时变量处理问题 我有一个结构体,并将其保存在会话变量中。

type User struct {
	ID   int
	Name string
	Priv string
	Type string
}

并且我在我的 init() 函数中有一个 gob 注册语句:

func init() {

	// sets session information
	store.Options = &sessions.Options{
		Domain:   "localhost",
		Path:     "/",
		MaxAge:   3600 * 8, // 8 hours
		HttpOnly: true,
	}

	gob.Register(User{})
}

我有下面这段代码来读取它,但我的 Go 技能在这里让我犯了难:

session, _ := store.Get(r, "session")
if err != nil {
	http.Error(w, err.Error(), http.StatusInternalServerError)
	return
}

var sessionVal interface{}
var person User

sessionVal, ok = session.Values["user"]
if ok {
	person, ok = sessionVal.(User)
	if !ok {
		log.Printf("The session is not a User struct")
		person = User{-1, "", "", ""}
	}
} else {
	log.Printf("There is no Session")
}

data := map[string]interface{}{
	"Authenticated": isAuthenticated(r), // This will let us know if the page is viewed anonymously
	"Reservations":  reservations,
	"TestUser":      person,
}

我想做的是检查 session.Values["user"] 是否存在,如果存在,就将其断言为 User 类型,以便稍后可以将其传递到我的模板 (data) 中。但如果它是空的,我理想情况下希望将 person 设置为 nil。如果做不到这一点,我也接受将 person 设置为一些默认值,就像你已经看到我尝试做的那样。但我对上下文以及 ok 何时有效、何时无效感到困惑。


更多关于Golang从session读取结构体时变量处理问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang从session读取结构体时变量处理问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


// 问题在于interface{}类型断言的处理逻辑,以下是更清晰的实现方式:

session, err := store.Get(r, "session")
if err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
    return
}

var person *User // 使用指针类型,可以设置为nil

if sessionVal, exists := session.Values["user"]; exists {
    if user, ok := sessionVal.(User); ok {
        person = &user // 获取结构体值的地址
    } else {
        log.Printf("Session value is not a User struct")
        person = nil // 明确设置为nil
    }
} else {
    log.Printf("No user in session")
    person = nil
}

// 模板数据中使用指针,模板可以处理nil值
data := map[string]interface{}{
    "Authenticated": isAuthenticated(r),
    "Reservations":  reservations,
    "TestUser":      person, // 现在可以是nil或有效的User指针
}

// 模板中可以通过{{if .TestUser}}检查是否存在

或者使用值类型的替代方案:

session, err := store.Get(r, "session")
if err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
    return
}

var person User
hasUser := false

if sessionVal, exists := session.Values["user"]; exists {
    if user, ok := sessionVal.(User); ok {
        person = user
        hasUser = true
    }
}

data := map[string]interface{}{
    "Authenticated": isAuthenticated(r),
    "Reservations":  reservations,
    "TestUser":      person,
    "HasUser":       hasUser, // 添加标志位供模板判断
}

对于类型断言失败的情况,建议添加更详细的日志:

if user, ok := sessionVal.(User); ok {
    person = &user
} else {
    // 记录实际类型以便调试
    log.Printf("Expected User type, got %T with value: %v", sessionVal, sessionVal)
    person = nil
}
回到顶部