当前位置: 首页 > 知识库问答 >
问题:

字符串从流中去为多个对象类型

孔建柏
2023-03-14

我已经习惯了Java,并在google go中设置了第一步。我有一个包含子对象等的对象树。。。此树递归地转储到io。作家输出可能很大,所以我不想为每个对象创建一个字符串,并将结果连接到内存中。。

出于调试目的,我想fmt。打印此树的部分。因此,我想在每个对象上创建一个通用的String()函数,其中调用ToStream函数,将结果作为字符串返回。Java,这很容易:在基类上创建方法。如何在GO中做到这一点,而无需为每种对象创建自定义String方法。

看到我想要的代码,特别是标有错误的行

package main

import (
"io"
"fmt"
"bytes"
)

//Base is an interface for bulk output
type Base interface {
    ToStream(io.Writer)
}

//Impl1 has interface Base
type Impl1 struct{
    stuff int
}

func (Impl1) ToStream(w io.Writer) {
    fmt.Fprintf(w, "A lot of stuff")
}

//Impl2 has interface Base
type Impl2 struct{
    otherstuff int
}

func (Impl2) ToStream(w io.Writer) {
    fmt.Fprintf(w, "A lot of other stuff")
}

//I want to convert any base to a sting for debug output
//This should happen by the ToStream method

func (v Base) String() string {//ERROR here: Invalid receiver type Base (Base is an interface type)
//func (v Impl1) String() string {//This works, but requires re-implementation for every struct Impl1,Impl2,...
    var buffer bytes.Buffer
    v.ToStream(&buffer)
    return string(buffer.Bytes())
}

func main(){
    aBase:= new(Impl1)
    fmt.Printf("%s\n",aBase)
}

共有3个答案

单昊穹
2023-03-14

首先打电话比较容易:

fmt.Printf("%+v\n", yourProject)

查看打印的信息是否足以开始:fmt包中提到

打印结构时,加号标志(%v)添加字段名

如果这还不够,那么你将不得不使用反射,正如我在“戈兰——如何在控制台中打印结构变量?”中提到的。

或者您可以查看项目daveggh/go-spew(在“go-spew:Dumping-go-Data-Structures”中提到)

Go-spew为Go数据结构实现了一个deep pretty打印机,以帮助调试

spew.Dump(myVar1, myVar2, ...)
spew.Fdump(someWriter, myVar1, myVar2, ...)
str := spew.Sdump(myVar1, myVar2, ...)

这会打印出如下内容:

(main.Foo) {
 unexportedField: (*main.Bar)(0xf84002e210)({
  flag: (main.Flag) flagTwo,
  data: (uintptr) <nil>
 }),
 ExportedField: (map[interface {}]interface {}) {
  (string) "one": (bool) true
 }
}
([]uint8) {
 00000000  11 12 13 14 15 16 17 18  19 1a 1b 1c 1d 1e 1f 20  |............... |
 00000010  21 22 23 24 25 26 27 28  29 2a 2b 2c 2d 2e 2f 30  |!"#$%&'()*+,-./0|
 00000020  31 32                                             |12|
}
弓华茂
2023-03-14

您可以环绕Base来添加必要的String()函数。这里有一个方法:

type StreamerToStringer struct {
    Base
}

func (s StreamerToStringer) String() string {
    var buffer bytes.Buffer
    s.Base.ToStream(&buffer)
    return string(buffer.Bytes())
}

有了它,您可以扩充任何Base实例,使其具有String()方法

func main() {
    aBase1 := StreamerToStringer{new(Impl1)}
    aBase2 := StreamerToStringer{new(Impl2)}
    fmt.Printf("%s\n", aBase1)
    fmt.Printf("%s\n", aBase2)

    // These wrapped values still support ToStream().
    var buffer bytes.Buffer
    aBase1.ToStream(&buffer)
    fmt.Println(buffer.Bytes())
}
吉和同
2023-03-14

似乎Java想法阻止了你:-)

虽然Java有方法,但只有Go有函数。当然,你不能在接口上有方法,但是你可以做一个简单的函数,用一个Base做一些事情:

func Base2String(b Base) string {
    var buffer bytes.Buffer
    b.ToStream(&buffer)
    return string(buffer.Bytes())
}

现在,如果你将Base重命名为Go-ish(记住Go中没有类型层次结构),你就有了一些不错的代码。

 类似资料:
  • 问题内容: 我的朋友给我发了一个问题,他在一次关于字符串对象的Java认证模拟考试中看到了一个问题: 调用此方法时将创建多少个字符串对象?考试给出的正确答案是3。但是我认为是5。 “嗨” “ 5” “ HI5” “H” “H” 我错了吗? 问题答案: String makeStrings() { String s = “HI”; //String literal s = s + “5”; //co

  • 问题内容: 尝试使用gson将以下json字符串解析为java对象 我有我的java类 转换后,我得到的提示对象为空。 有人可以纠正我吗 问题答案: 试试这个JSON: 使用此Java类: 奇迹般有效 输出:

  • 问题内容: 我目前正在做一个数据转换项目,需要从字符串中剥离所有字母字符。不幸的是,由于我们不拥有源计算机,因此我无法创建或使用函数,从而使我无法通过搜索以前的帖子找到的方法。 在select语句中执行此操作的最佳方法是什么?速度不是一个太大的问题,因为它只能运行30,000左右左右的记录,而且是一次过的声明。 问题答案: RichardTheKiwi的脚本中用于无交叉选择的选择中的函数,还添加了

  • 我最近开始处理Java流。我试图从我的一个SQL查询的结果集中获取字符串值。结果集只从数据库中选择一个字符串/Varchar列。 所以我做了: 或: 我相信地图具有将数据从一种类型转换为另一种类型的功能。在本例中,从对象到字符串,然后在字符串列表中收集它们。 但上面的代码显示了编译时错误:无法从对象转换为字符串列表。 请给我建议正确的做法,并说明我的理解有什么问题。

  • 问题内容: 我想获取一串字符串并将其转换为单词对流。例如: 我有: 我想要:。 这几乎与Zipping相同,如使用带有Lambda的JDK8的Zipping流中概述的那样(java.util.stream.Streams.zip) 但是,这会产生: 以下代码有效,但显然是错误的方法(不是线程安全的等): 问题答案: 如果你: 不喜欢使用流中所有字符串创建列表的想法 不想使用外部库 喜欢弄脏你的手

  • 我正在做一个项目,在那里用户可以写其他用户的邮件。邮件类当前如下所示: 现在,问题是,我需要将所有邮件保存到. yml用户数据文件中。对我来说,最简单的方法是首先将每封邮件转换为字符串,然后将所有邮件保存到