Converters
API reference for converting dynamic row values into common Go types.
Mapper provides small helper functions for converting dynamic values from map[string]any rows into common Go types.
These helpers are useful when working with:
ScanMapRowsmapper.Row- custom
ScanMapperimplementations - manually processed database values
The converters return the converted value and a boolean result.
value, ok := mapper.AsString(v)If conversion succeeds, ok is true.
If the value cannot be converted, ok is false.
Overview
| Function | Returns | Purpose |
|---|---|---|
AsInt | (int, bool) | Convert a value to int |
AsInt64 | (int64, bool) | Convert a value to int64 |
AsString | (string, bool) | Convert a value to string |
AsBool | (bool, bool) | Convert a value to bool |
AsTime | (time.Time, bool) | Convert a value to time.Time |
AsInt
AsInt converts common numeric values into int.
id, ok := mapper.AsInt(row["id"])
if !ok {
return errors.New("invalid id")
}Supported source values include:
intint8int16int32int64float32float64
Example:
row := map[string]any{
"id": int64(123),
}
id, ok := mapper.AsInt(row["id"])
if !ok {
return errors.New("invalid id")
}
fmt.Println(id)AsInt64
AsInt64 converts common numeric values into int64.
id, ok := mapper.AsInt64(row["id"])
if !ok {
return errors.New("invalid id")
}Supported source values include:
intint8int16int32int64float32float64
Example:
row := map[string]any{
"id": int64(123),
}
id, ok := mapper.AsInt64(row["id"])
if !ok {
return errors.New("invalid id")
}
fmt.Println(id)AsString
AsString converts string-like values into string.
name, ok := mapper.AsString(row["name"])
if !ok {
return errors.New("invalid name")
}Supported source values:
string[]byte
Example:
row := map[string]any{
"name": []byte("Alice"),
}
name, ok := mapper.AsString(row["name"])
if !ok {
return errors.New("invalid name")
}
fmt.Println(name)If the value is not a string or byte slice, conversion fails.
AsBool
AsBool converts boolean-like values into bool.
active, ok := mapper.AsBool(row["active"])
if !ok {
return errors.New("invalid active value")
}Supported source values include:
bool- signed integer types
- unsigned integer types
- floating point types
- common boolean strings
[]bytecontaining a supported boolean string
Numeric values are converted using zero/non-zero behavior.
0 // false
1 // trueSupported true strings:
1trueTRUETrueyesYESYesyY
Supported false strings:
0falseFALSEFalsenoNONonN
Example:
row := map[string]any{
"active": "yes",
}
active, ok := mapper.AsBool(row["active"])
if !ok {
return errors.New("invalid active value")
}
fmt.Println(active)AsTime
AsTime converts time-like values into time.Time.
createdAt, ok := mapper.AsTime(row["created_at"])
if !ok {
return errors.New("invalid created_at value")
}Supported source values:
time.Timestring[]byte
String and byte slice values are parsed using common time layouts.
Supported layouts include:
2006-01-02 15:04:052006-01-02time.RFC3339time.RFC3339Nano
Example:
row := map[string]any{
"created_at": "2026-05-22 14:30:00",
}
createdAt, ok := mapper.AsTime(row["created_at"])
if !ok {
return errors.New("invalid created_at value")
}
fmt.Println(createdAt)Row Converter Methods
The same conversions are also available through the mapper.Row type.
row := mapper.Row{
"id": int64(123),
"name": "Alice",
"active": true,
"created_at": time.Now(),
}Use typed methods to access values by key.
id, ok := row.Int64("id")
if !ok {
return errors.New("invalid id")
}
name, ok := row.String("name")
if !ok {
return errors.New("invalid name")
}
active, ok := row.Bool("active")
if !ok {
return errors.New("invalid active value")
}
createdAt, ok := row.Time("created_at")
if !ok {
return errors.New("invalid created_at value")
}Available methods:
| Method | Uses | Returns |
|---|---|---|
row.Int(key) | AsInt | (int, bool) |
row.Int64(key) | AsInt64 | (int64, bool) |
row.String(key) | AsString | (string, bool) |
row.Bool(key) | AsBool | (bool, bool) |
row.Time(key) | AsTime | (time.Time, bool) |
Custom Mapping Example
Converters are especially useful when implementing ScanMapper.
type User struct {
ID int64
Name string
Active bool
CreatedAt time.Time
}
func (u *User) ScanMap(row map[string]any) error {
id, ok := mapper.AsInt64(row["id"])
if !ok {
return errors.New("invalid id")
}
name, ok := mapper.AsString(row["name"])
if !ok {
return errors.New("invalid name")
}
active, ok := mapper.AsBool(row["active"])
if !ok {
return errors.New("invalid active value")
}
createdAt, ok := mapper.AsTime(row["created_at"])
if !ok {
return errors.New("invalid created_at value")
}
u.ID = id
u.Name = name
u.Active = active
u.CreatedAt = createdAt
return nil
}Conversion Failures
Converters do not return errors.
They return ok = false when conversion is not possible.
id, ok := mapper.AsInt64(row["id"])
if !ok {
return errors.New("invalid id")
}This keeps converter usage simple and predictable.
Use explicit error handling in your own code when a value is required.
Recommended Usage
Use converters when working with dynamic row data.
err := mapper.ScanMapRows(rows, func(row map[string]any) error {
name, ok := mapper.AsString(row["name"])
if !ok {
return errors.New("invalid name")
}
fmt.Println(name)
return nil
})Use struct scanning when the result shape is known.
users, err := mapper.ScanStructSlice[User](rows)Use converters when you need custom parsing, validation, or dynamic row handling.