diese Tabelle Struktur:Verwirrt über benutzerdefinierte Typen in SQL, wenn sql.DB.Exec
CREATE TABLE `tableName` (
`Id` int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
`Status` enum('pending','rejected','sent','invalid') NOT NULL,
`Body` varchar(255) NULL
) ENGINE='MyISAM' COLLATE 'utf8_general_ci';
Ich habe dies (nicht vollständig) Code fein Arbeits: meine Frage
type StatusEnum string
const (
STATUS_PENDING StatusEnum = "pending"
STATUS_REJECTED StatusEnum = "rejected"
STATUS_SENT StatusEnum = "sent"
STATUS_INVALID StatusEnum = "invalid"
)
func (s *StatusEnum) Scan(src interface{}) error {
if src == nil {
return errors.New("This field cannot be NULL")
}
if stringStatus, ok := src.([]byte); ok {
*s = StatusEnum(string(stringStatus[:]))
return nil
}
return errors.New("Cannot convert enum to string")
}
func (s *StatusEnum) Value() (driver.Value, error) {
return []byte(*s), nil
}
type EmailQueue struct {
Id uint64
Status StatusEnum
Body sql.NullString
}
func Save (db *sql.DB) error {
_, err = db.Exec(
"UPDATE `tableName` SET `Status` = ?, `Body` = ? WHERE `id` = ?",
&eqi.Status,
eqi.Body,
eqi.Id,
)
return err
}
So ist: Warum muss ich die Zeigerreferenz (&eqi.Status
) auf db.Exec
verwenden?
Beide sql.NullString
und meine Gewohnheit StatusEnum
nicht in github.com/go-sql-driver/mysql
implementiert, warum also der Unterschied?
Wenn ich den Zeigerverweis nicht (eqi.Status
), erhalte ich diesen Fehler (wirft in database/sql/convert.go):
sql: converting Exec argument #0's type: unsupported type emailqueue.StatusEnum, a string
Ich habe versucht, einige andere Schnittstellen zu implementieren ich nicht gefunden habe Glück.
Ich habe andere benutzerdefinierte Typen mit sql.Scanner
und sql.driver.Valuer
Schnittstellen implementiert, aber das Problem ist das gleiche.
ich raten, über struct
und Typ Vererbung Differenzierung, aber ich konnte jeden Hinweis auf, dass nicht bekommen ... :(
Bitte helfen zu verstehen, was vor sich geht. Dank !!! :)
Entschuldigung, ich habe den Code repariert '' 'EmailList''' mit' '' StatusEnum''' ersetzt. Dies ist jedoch verwirrender, weil dieser Code einfach perfekt funktioniert: '' 'v, err: = eqi.Status.Value() \t v, err = (& eqi.Status) .Wert()' '' –
Für alle, die reinkommen und das Lesen, weil Sie eine Pointer-Methode auf einen Nicht-Pointer-Wert aufrufen können und automatisch die Adresse übernimmt, aber nur, wenn es sich um eine Nicht-Interface-Methode handelt, dh die Variable ist eine Schnittstelle. https://golang.org/ref/spec#Method_values –