Your Question

`type Status int

// Scan 实现 Scanner 接口,用于将数据库的值映射到枚举类型 func (s Status) Scan(value any) error { switch v := value.(type) { case int64: s = Status(value.(int64)) case []uint8: data := string(v) parseInt, _ := strconv.ParseInt(data, 10, 64) *s = Status(parseInt) default: return fmt.Errorf("unsupported scan type %T", value) } return nil }

// Value 实现 Valuer 接口,用于将枚举类型映射为数据库的值 func (s Status) Value() (driver.Value, error) { return s, nil }

type Users struct { Name string Type Status }

func main() { dsn := "root:123456@tcp(127.0.0.1:3306)/go_test?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.New(mysql.Config{ DSN: dsn}), &gorm.Config{}) if err != nil { panic(err) } err = db.AutoMigrate(&Users{}) if err != nil { return } var use []Users var uses []Users db.Table("users").Where("id = ?", 1).Find(&use) db.Find(&uses) `

db.Table("users").Where("id = ?", 1).Find(&use) ------- Scan value.(type) == int64
db.Find(&uses) ------ Scan value.(type) == []uint8

The document you expected this should be explained

Expected answer

I want to know why the input parameters of the scan method are different after executing these two lines of code.

Comment From: github-actions[bot]

The issue has been automatically marked as stale as it missing playground pull request link, which is important to help others understand your issue effectively and make sure the issue hasn't been fixed on latest master, checkout https://github.com/go-gorm/playground for details. it will be closed in 30 days if no further activity occurs. if you are asking question, please use the Question template, most likely your question already answered https://github.com/go-gorm/gorm/issues or described in the document https://gorm.io ✨ Search Before Asking

Comment From: paradox-lab2

I tried to reproduce the problem you described, however, Scan value.(type) in db.Find(&uses) is int64 but not []uint8.

the first step, i started mysql using docker:

docker run --name gorm7201 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=go_test --rm -d -p 3306:3306 mysql:8.0.40

and then go run main.go.

here's my complete test code:

package main

import (
    "database/sql/driver"
    "fmt"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "reflect"
    "strconv"
)

type Status int

// Scan 实现 Scanner 接口,用于将数据库的值映射到枚举类型
func (s *Status) Scan(value any) error {
    fmt.Println(value, reflect.TypeOf(value))

    switch v := value.(type) {
    case int64:
        *s = Status(value.(int64))
    case []uint8:
        data := string(v)
        parseInt, _ := strconv.ParseInt(data, 10, 64)
        *s = Status(parseInt)
    default:
        return fmt.Errorf("unsupported scan type %T", value)
    }
    return nil
}

// Value 实现 Valuer 接口,用于将枚举类型映射为数据库的值
func (s Status) Value() (driver.Value, error) {
    return s, nil
}

type Users struct {
    ID   uint
    Name string
    Type Status
}

func main() {
    dsn := "root:123456@tcp(127.0.0.1:3306)/go_test?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.New(mysql.Config{
        DSN: dsn}), &gorm.Config{})
    if err != nil {
        panic(err)
    }
    err = db.AutoMigrate(&Users{})
    if err != nil {
        return
    }

    var count int64
    db.Model(&Users{}).Count(&count)
    if count == 0 {
        // setup data
        db.Exec(`
insert into go_test.users (id, name, type)
values  (1, 'user1', 0),
        (2, 'user2', 1),
        (3, 'user3', 2),
        (4, 'user4', 3),
        (5, 'user5', 4),
        (6, 'user6', 5),
        (7, 'user7', 6),
        (8, 'user8', 7),
        (9, 'user9', 8),
        (10, 'user10', 9);
`)
    }

    var use []Users
    var uses []Users
    db.Table("users").Where("id = ?", 1).Find(&use)
    fmt.Println("-----------------------------------------------")
    db.Find(&uses)
}

the output is

0 int64
-----------------------------------------------
0 int64
1 int64
2 int64
3 int64
4 int64
5 int64
6 int64
7 int64
8 int64
9 int64

dependencies version

gorm.io/driver/mysql v1.5.7
gorm.io/gorm v1.25.12