go-gin-api 兩個被頻繁問到的代碼寫法問題

前言

根據使用者的反饋,回答關於開源項目:go-gin-api[1] 中被頻繁問到的兩個代碼寫法問題。

以如下代碼片段爲例:

  1. 第 8 行,這種寫法是什麼意思?

  2. 第 11 行,爲什麼定義一個 i() 方法?

問題一

var _ Signature = (*signature)(nil)

這代碼是什麼意思?

強制 *signature 去實現 Signature 接口,編譯器會檢查 *signature 類型是否實現了 Signature 接口。

來看一個例子:

package main

import "fmt"

var _ Study = (*study)(nil)

type study struct {
 Name string
}

type Study interface {
 Listen(message string) string
}

func main() {
 fmt.Println("hello world")
}

上面代碼會輸出 hello world 嗎?

不會!

這時會輸出:

./main.go:5:5: cannot use (*study)(nil) (type *study) as type Study in assignment:
 *study does not implement Study (missing Listen method)

如果去掉這一行:

var _ Study = (*study)(nil)

這時就可以輸出 hello world 了。

問題二

i()

爲什麼在接口中定義一個 i() 方法?

強制 Signature 接口中所有方法只能在本包中去實現,在其他包中不允許去實現。因爲接口中有小寫方法,所以在其他包無法去實現。i() 表示一個小寫方法,起其他名字也可以。

來看一個例子:

package study

type Study interface {
 Listen(message string) string
 i()
}

func Speak(s Study) string {
 return s.Listen("abc")
}

定義了一個 Study 接口,接口中包含兩個方法,其中就有一個 i() 。

定義了一個 Speak 方法,入參是 Study 接口,方法體是執行接口中的 Listen 方法。

接下來看另一個文件:

type stu struct {
 Name string
}

func (s *stu) Listen(message string) string {
 return s.Name + " 聽 " + message
}

func (s *stu) i() {}

func main() {
 message := study.Speak(new(stu))
 fmt.Println(message)
}

定義了一個 stu 結構體,這個結構體實現了 Study 接口中的方法,那麼上述程序會正常輸出嗎?

不會!

這時會輸出:

./main.go:19:28: cannot use new(stu) (type *stu) as type study.Study in argument to study.Speak:
 *stu does not implement study.Study (missing study.i method)
  have i()
  want study.i()

如果去掉接口中 i(),會正常輸出:聽 abc

小結

以上兩個是讀者在學習代碼的過程中最常問的問題,希望這次能夠幫大家解惑。

另外 option 設計模式,問的也不少,大家可以看下這篇文章:《函數的不定參數你是這樣用嗎?

參考資料

[1]

go-gin-api: https://github.com/xinliangnote/go-gin-api

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/gpMzEoRofGE9LmayeYw1qw