官术网_书友最值得收藏!

What does this mean for Go?

In Chapter 1Never Stop Aiming for Better, we mentioned the popular Go idiom coined by Jack Lindamoodaccept interfaces, return structs. Combine this idea with the ISP and things start to take off. The resultant functions are very concise about their requirements and, at the same time, they are quite explicit regarding their outputs. In other languages, we might have to define the outputs in the form of an abstraction or create adapter classes to decouple our function from our users entirely. However, given Go's support for implicit interfaces, there is no need for this.

Implicit interfaces are a language feature whereby the implementor (that is, the struct) does not need to define the interfaces that it implements, but rather only needs to define the appropriate methods to satisfy the interface, as shown in the following code:

type Talker interface {
SayHello() string
}

type Dog struct{}

// The method implicitly implements the Talker interface
func (d Dog) SayHello() string {
return "Woof!"
}

func Speak() {
var talker Talker
talker = Dog{}

fmt.Print(talker.SayHello())
}

This might seem like a neat trick to cut down on typing, and it is. However, that is not the only reason to use it. When using explicit interfaces, the implementing object becomes somewhat coupled with its dependents as there is a rather explicit link between them. However, perhaps the most significant reason is simplicity. Let's look at one of the most popular interfaces in Go that you've probably never heard of:

// Stringer is implemented by any value that has a String method, which 
// defines the “native” format for that value. The String method is used
// to print values passed as an operand to any format that accepts a
// string or to an unformatted printer such as Print.

type Stringer interface {
String() string
}

This interface might not look impressive, but the fact that the fmt package supports this interface allows you to do the following:

func main() {
kitty := Cat{}

fmt.Printf("Kitty %s", kitty)
}

type Cat struct{}

// Implicitly implement the fmt.Stringer interface
func (c Cat) String() string {
return "Meow!"
}

If we had explicit interfaces, imagine how many times we would have to declare that we implement Stringer. Perhaps where implicit interfaces give us the most significant advantage in Go is when they are combined with the ISP and DI. The combination of the three allows us to define input interfaces that are thin, specific to the particular use case, and decoupled from everything else, as we saw with the Stringer interface.

Furthermore, defining interfaces in the package in which they are used narrows the scope of knowledge required to work on a piece of code, which in turn makes it much easier to understand and test.

主站蜘蛛池模板: 齐河县| 仁寿县| 行唐县| 宜昌市| 馆陶县| 恭城| 康定县| 高邮市| 横山县| 五峰| 连山| 紫金县| 灌阳县| 海阳市| 南通市| 砀山县| 伽师县| 紫云| 康乐县| 左云县| 交城县| 沅陵县| 玉山县| 石楼县| 越西县| 许昌县| 鄂伦春自治旗| 辉县市| 洮南市| 新竹市| 旺苍县| 淮安市| 蒲江县| 观塘区| 淅川县| 高雄县| 栾城县| 富宁县| 舒城县| 禹城市| 海口市|