在Golang的接口中尝试使用指针
首先
最近我在学习RUST,但为了不忘记以前学过的Golang,我会利用Go之旅进行复习。为了不忘记对接口的理解,我会在这里留下笔记,提醒自己重点是结构体、指针和接口。
目标
part1: 使接口能夠輸出指標
part2: 當接口指定輸出類型時,可以利用指標指定的類別重新定義錯誤
测试代码
部分1
请使用中文进行重述,只需要提供一个选项:
package main
import "fmt"
// インタフェース
type I interface {
M()
}
// 構造体
type mystring struct {
S string
}
// mystringのポインタクラス
func (f *mystring) M() {
if f == nil {
fmt.Println("<nil>")
return
}
fmt.Println("print S value {}", f.S)
}
// メインメソッド
func main() {
var i I
var t *mystring
i = t
describe(i)
i.M()
}
func describe(i I) {
fmt.Printf("describe the result (%v, %T)\n", i, i)
}
输出结果:
describe the result (<nil>, *main.mystring)
<nil>
我們可以從這裡看出來,定義了一個名為「t」的結構體指針,並且通過傳遞介面「i」來進行輸出。
package main
import "fmt"
// インタフェース
type I interface {
M()
}
// 構造体
type mystring struct {
S string
}
// mystringのポインタクラス
func (f *mystring) M() {
if f == nil {
fmt.Println("<nil>")
return
}
fmt.Printf("print S value is %v ,pointer is %v", f.S, &f.S)
}
// メインメソッド
func main() {
var i I
var middlestring = mystring{"Mike"}
i = &middlestring
describe(i)
i.M()
}
func describe(i I) {
fmt.Printf("describe the result (%v, %T)\n", i, i)
}
输出结果
describe the result (&{Mike}, *main.mystring)
print S value is Mike ,pointer is 0xc000108050
我可以输出指针。
把以下内容翻译成中文,只需一种选项:
第二部分
package main
import (
"fmt"
"time"
)
type error interface {
Error() string
}
type error2 interface {
Error2() string
}
type MyError struct {
When time.Time
What string
}
func (e *MyError) Error2() string {
return fmt.Sprintf("at222 %v, %s",
e.When, e.What)
}
func (e *MyError) Error() string {
return fmt.Sprintf("at %v, %s",
e.When, e.What)
}
func run2() error2 {
return &MyError{
time.Now(),
"it didn't works",
}
}
func run() error {
return &MyError{
time.Now(),
"it didn't work",
}
}
func main() {
if err := run(); err != nil {
fmt.Println(err)
}
if err2 := run2(); err2 != nil {
fmt.Println(err2)
}
}
输出结果
at 2009-11-10 23:00:00 +0000 UTC m=+0.000000001, it didn't work
at 2009-11-10 23:00:00 +0000 UTC m=+0.000000001, it didn't works <- ※※おかしい
根据结果来看,run2()的返回结果是一个名为”Error()”的类。很奇怪的是,这是否是默认接口的意思?
package main
import (
"fmt"
"time"
)
type error interface {
Error() string
}
type error2 interface {
Error2() string
}
type MyError struct {
When time.Time
What string
}
func (e *MyError) Error2() string {
return fmt.Sprintf("at222 %v, %s",
e.When, e.What)
}
func (e *MyError) Error() string {
return fmt.Sprintf("at %v, %s",
e.When, e.What)
}
func run2() interface{} {
return func() interface{} {
var Error2 error2
Error2 = &MyError{time.Now(), "it didn't works"}
return Error2.Error2()
}() # <-- ここは「()」を使用しないとポインターを返す
}
func run() error {
return &MyError{
time.Now(),
"it didn't work",
}
}
func main() {
if err := run(); err != nil {
fmt.Println(err)
}
if err2 := run2(); err2 != nil {
fmt.Println(err2)
}
}
输出结果
at 2009-11-10 23:00:00 +0000 UTC m=+0.000000001, it didn't work
at222 2009-11-10 23:00:00 +0000 UTC m=+0.000000001, it didn't works
最后,虽然不知道原因,但总算是通过定义接口并重新引入error2接口,将run2()的返回结果设定为返回策略,并解决了问题。
总结
- 既存なデフォルトインタフェースをしておくべきかな。