I'm working on a project that consume messages from Kafka, unmushal using messagepack or json format, build sql of it and insert them into TDengine database.
The inteface defined as:
type TaosEncoder interface {
TaosDatabase() string
TaosSTable() string
TaosTable() string
TaosTags() []interface{}
TaosCols() []string
TaosValues() []interface{}
}
For an object called Record
:
type Record struct {
DeviceID string `json:"deviceID"` // for table name
Timestamp time.Time `json:"timestamp"`
Cols []interface{} `json:"cols"`
}
Implement the interface:
func (r *Record) TaosCols() []string {
var tags []string
return tags
}
// other methods are implemented too
A method will use the interface methods:
func ToTaosBatchInsertSql(l []interface{}) (string, error) {
records := make([]string, len(l))
for i, t := range l {
// type TaosEncoderT = *TaosEncoder
record, err := ToTaosRecordSql(t.(TaosEncoder))
if err != nil {
return "", err
}
records[i] = record
}
return fmt.Sprintf("insert into %s", strings.Join(records, " ")), nil
}
Use it as this:
records := make([]interface{}, size)
for i := 0; i < size; i++ {
item := <-q.queue # an channel of Record, defined as: queue chan interface{}
records[i] = item
}
sqlStr, err := utils.ToTaosBatchInsertSql(records)
It compiles ok, but failed while running like this:
panic: interface conversion: record.Record is not utils.TaosEncoder: missing method TaosCols
goroutine 71 [running]:
xxx/pkg/utils.ToTaosBatchInsertSql(0xc000130c80, 0xc8, 0xc8, 0xc8, 0x0, 0x0, 0x0)
But when I change the implementations of Record - remove *
func (r Record) TaosCols() []string {
var tags []string
return tags
}
Then it just works.
I've told to use *
in interface implements, so the question is:
func (r Record) xxx
?The cause of this error is related to the method sets of a type.
Assume a type T
that has methods with a receiver type of T
and some more methods with a receiver type of *T
.
Then, if a variable is of type T
, it has all methods available that have a pointer receiver of T
but none of the methods with receiver type *T
.
If a variable is of type *T
, it has both sets of methods available, those with receiver type T
, and those with receiver type *T
.
In your case, type Record
has no TaosCols()
method, and so it does not implement interface TaosEncoder
completely.
If you turn the variable of type Record
into a *Record
variable, it has all methods available and then would implement the interface.
Method Sets in: Frequently Asked Questions (FAQ) - The Go Programming Language
Method Sets in: The Go Programming Language Specification - The Go Programming Language
A Record
is not the same type as a *Record
. If you use a pointer receiver for defining the methods that implement the interface, then only *Record
implements TaosEncoder
.
Based on this:
item := <-q.queue # an channel of Record
it looks like you will need to send a value of *Record
on q.queue
, rather than a Record
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.