在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()的返回结果设定为返回策略,并解决了问题。

总结

    既存なデフォルトインタフェースをしておくべきかな。