简体   繁体   中英

golang initializing struct with embedded template: too few values in struct initializer

I'm trying to initialize a golang struct with an embedded template. Since templates have no fields, I would expect that assigning the correct number of variables to a constructor would work, but instead the compiler complains that

main.go:17:19: too few values in struct initializer

package main

import "fmt"

type TestTemplate interface {
    Name() string
}

type TestBase struct {
    name       string

    TestTemplate
}

func New(name string) *TestBase {
    return &TestBase{name} // This fails
    //return &TestBase{name: name} // This works
}

func (v *TestBase) Name() string {
    return v.name
}

func main() {
    fmt.Println(New("Hello"))
}

https://golang.org/ref/spec#Struct_types

An embedded field is still a field , the name of which is derived from its type, therefore TestBase has actually two fields and not one, namely name and TestTemplate .

This compiles just fine:

var t *TestBase
t.TestTemplate.Print()

So when initializing TestBase you either specify the field names or you initialize all fields.

These all compile:

_ = &TestBase{name, nil}
_ = &TestBase{name: name}
_ = &TestBase{name: name, TestTemplate: nil}
_ = &TestBase{TestTemplate: nil}

It looks like (as far as general concepts go) you're confusing interface s with composition (which is kind of how Go approaches the whole inheritance question.

This post might be helpful for you: https://medium.com/@gianbiondi/interfaces-in-go-59c3dc9c2d98

So TestTemplate is an interface.

That means that the struct TestBase will implement the methods (whose signature is) defined in the interface.

You should implement Print for TestBase .

But in anycase the error you're getting is because when you initialize a struct with no field names specified, it expects all the field names to be entered, see

https://gobyexample.com/structs

So remove the composition TestTemplate from the struct (and implement the method defined in the interface instead), and it should work.

Also, FYI, the Stringer interface with String method is what fmt.Println expects to print an arbitrary struct (not a Print method) see: https://tour.golang.org/methods/17

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM