通过引用修改接口值

huangapple go评论79阅读模式
英文:

Change interface value by reference

问题

package main

import (
	"fmt"
)

// -------- Library code. Can't change ------------
type Client struct {
	transport RoundTripper
}

type RoundTripper interface {
	Do()
}

type Transport struct{}

func (d Transport) Do() {}

var DefaultTransport RoundTripper = Transport{}

// -------- My code. Can change ------------
func changeTransport(r RoundTripper) {
	if r == nil {
		fmt.Println("transport is nil")
		r = DefaultTransport
	}
}

func main() {
	c := Client{}
	changeTransport(c.transport)
	fmt.Println(c.transport)
}

输出:

transport is nil
<nil>

期望输出:

transport is nil
{}

我还根据 https://stackoverflow.com/a/44905592/6740589 尝试了以下代码:

func changeTransport(r RoundTripper) {
	if r == nil {
		fmt.Println("transport is nil")
		d, ok := DefaultTransport.(Transport)
		if !ok {
			log.Fatal("impossible")
		}

		if t, ok := r.(*Transport); ok {
			t = &d
			fmt.Println("ignoreme", t)
		} else {
			log.Fatal("Uff")
		}

	}
}

输出:

transport is nil
2009/11/10 23:00:00 Uff

Playground

英文:
package main

import (
	&quot;fmt&quot;
)

// -------- Library code. Can&#39;t change ------------
type Client struct {
	transport RoundTripper
}

type RoundTripper interface {
	Do()
}

type Transport struct{}

func (d Transport) Do() {}

var DefaultTransport RoundTripper = Transport{}

// -------- My code. Can change ------------
func changeTransport(r RoundTripper) {
	if r == nil {
		fmt.Println(&quot;transport is nil&quot;)
		r = DefaultTransport
	}
}

func main() {
	c := Client{}
	changeTransport(c.transport)
	fmt.Println(c.transport)
}

Output:

transport is nil
&lt;nil&gt;

Expected:

transport is nil
{}

Playground

I also tried this based on https://stackoverflow.com/a/44905592/6740589:

func changeTransport(r RoundTripper) {
	if r == nil {
		fmt.Println(&quot;transport is nil&quot;)
		d, ok := DefaultTransport.(Transport)
		if !ok {
			log.Fatal(&quot;impossible&quot;)
		}

		if t, ok := r.(*Transport); ok {
			t = &amp;d
			fmt.Println(&quot;ignoreme&quot;, t)
		} else {
			log.Fatal(&quot;Uff&quot;)
		}

	}
}

Output:

transport is nil
2009/11/10 23:00:00 Uff

Playground

答案1

得分: 1

使用RoundTripper接口的指针作为changeTransport函数的参数来改变指针的值:

// -------- 我的代码。可以改变 ------------
func changeTransport(r *RoundTripper) {
	if r != nil && *r == nil {
		fmt.Println("transport is nil")
		*r = DefaultTransport
	}
}

func main() {
	c := Client{}
	changeTransport(&c.transport)
	fmt.Println(c.transport)
}

输出结果为:

transport is nil
{}

PLAYGROUND

英文:

Use pointer of the RoundTripper interface as the changeTransport function argument to change pointer's value:

// -------- My code. Can change ------------
func changeTransport(r *RoundTripper) {
	if r != nil &amp;&amp; *r == nil {
		fmt.Println(&quot;transport is nil&quot;)
		*r = DefaultTransport
	}
}

func main() {
	c := Client{}
	changeTransport(&amp;c.transport)
	fmt.Println(c.transport)
}
transport is nil
{}

<kbd>PLAYGROUND</kbd>

huangapple
  • 本文由 发表于 2023年4月27日 18:42:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76119476.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定