当前位置: 首页 > 面试题库 >

为什么我的Stringer接口方法没有被调用?使用fmt.Println时

左丘涵畅
2023-03-14
问题内容

假设我有以下代码:

package main

import "fmt"

type Car struct{
    year int
    make string
}

func (c *Car)String() string{
    return fmt.Sprintf("{make:%s, year:%d}", c.make, c.year)
}

func main() {
    myCar := Car{year:1996, make:"Toyota"}
    fmt.Println(myCar)
}

当我调用fmt.Println(myCar)且有问题的对象是指针时,我的String()方法将被正确调用。如果该对象是一个值,则使用Go内置的默认格式对我的输出进行格式化,而不会调用用于格式化该对象的代码。

有趣的是,无论哪种情况,如果我手动调用myCar.String(),无论我的对象是指针还是值,它都能正常工作。

与Println一起使用时,无论对象是基于值还是基于指针,如何以所需的方式格式化对象?

我不想为String使用value方法,因为那样就意味着每次调用它时,都会复制该对象,从而造成不合理的连接。而且我也不想总是手动调用.String(),因为我正试图让鸭子键入系统来工作。


问题答案:

从函数签名可以看到,调用时fmt.PrintlnmyCar将隐式转换为type的值interface{}fmt包中的代码然后进行类型切换以弄清楚如何打印此值,如下所示:

switch v := v.(type) {
case string:
    os.Stdout.WriteString(v)
case fmt.Stringer:
    os.Stdout.WriteString(v.String())
// ...
}

但是,该fmt.Stringer案例失败了,因为Car未实现String(如上定义*Car)。String手动调用有效,因为编译器认为String需要a
*Car,因此会自动转换myCar.String()(&myCar).String()。对于任何有关接口的内容,您都必须手动进行。因此,您要么必须实现StringCar要么总是将指针传递给fmt.Println

fmt.Println(&myCar)


 类似资料:
  • 问题内容: 当我发现抽象类和接口之间的区别时,这个问题就浮现在脑海中。在这篇文章中,我知道接口很慢,因为它们需要额外的间接访问。但是我没有得到接口而不是抽象类或具体类所需的间接类型,请对此进行澄清。提前致谢 问题答案: 关于性能的神话很多,有些可能在几年前是正确的,而在没有JIT的VM上可能仍然正确。 Android文档(请记住,Android没有JVM,而是Dalvik VM)曾经说过,在接口上

  • 我是android开发的初学者。我正在尝试制作一个SMS计划程序。我的应用程序的广播接收器的onReceive()方法没有被调用?下面给出了我的源代码。我看了一些其他的链接,像基本的Android报警应用程序,广播接收器的onReceive()方法没有被调用请,我想知道我哪里做错了。提前谢谢。 > homepage.java } TimePickerFragment.java {public Ca

  • 问题内容: 从log.go(执行日志包): 只是一个函数包装器,为什么我应该用它代替or ? 有实际原因吗? 问题答案: 两件事不同: 通过包日志进行打印对于并发goroutine是安全的(而普通的则不是) 日志可以自动添加计时信息。 因此,这是两件完全不同的事情。log用于记录和格式化。(好吧,log使用相同的动词和标志,但这很方便)。

  • 问题内容: 我有一个JPanel,它打算充当游戏的HUD,自然,我已经重写了paint方法来进行自己的自定义显示,但确实会调用此方法,但是仅在调整大小或最大化,最小化框架时才调用,我的游戏循环告诉它repaint()。由于另外两个面板完全重新粉刷,对我来说,这尤其奇怪。 这是我的HUD课: 它在我的游戏类更新以及其他两个面板中被调用 由我的JFrame调用 很长一段时间以来一直在试图解决这个问题,

  • 问题内容: 我不应该能够调用实例化对象的私有方法。我想知道为什么下面的代码有效。 我知道可以从类中访问私有方法。但是,如果类中的方法实例化了同一类的对象,则作用域规则是否不适用于该实例化的对象? 如本例所示,像main这样的静态方法可以访问类的非静态成员吗​​? 问题答案: 您的方法是的方法,因此可以调用的私有方法。 只是因为它是一个方法并不妨碍它表现得像为目的的方法,等等。 只是阻止的方法 等

  • 我知道这是一个很基本的问题,但一个面试官用一种很诡计的方式问我,我很无奈:( 我只知道一个界面的材料或理论定义,并在我工作的许多项目中实现了它。但我真的不明白这为什么有用,怎么有用。 接口方面有一点我也不懂。例如,我们使用 finally块中的。但我没有看到该类实现或继承接口()类,我的意思是。我想知道怎么才能直接调用方法名。同样,我不理解Dispose方法是如何工作的,因为我们需要用我们自己的实