在Golang中如何创建一个没有字段或方法的顶级对象?

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

How to create a top level object with no fields or methods in Golang?

问题

由于我来自Java并且对Golang不熟悉,我将尝试用Java来解释我想要的内容。

interface Car { }

class MyCarA implements Car {
  int specificToA;
}

class MyCarB implements Car {
  int specificToB;
}

我认为在Java中,这样的接口(如Car)被称为标记接口。它只是为了向编译器指示必要的抽象。

在Golang中,你可以这样做:

type Car interface {}

type MyCarA struct {
   specificToA int
}

type MyCarB struct {
  specificToB int
}

现在你想要如何将这些结构体泛化?它应该是一个接口还是另一个结构体?

英文:

Since I am from Java and new to Golang, I will try to explain what I want in Java.

    interface Car { }

    class MyCarA implements Car {
      int specificToA
    }

    class MyCarB implements Car {
      int specificToB
    }

I think such an interface (like Car) is called a marker interface in Java. It is just to indicate the compiler the necessary abstraction.

How can I do this in Golang ?

I have

type MyCarA struct {
   specificToA int
}
type MyCarB struct {
  specificToB int
}

How can I generalise these structs now ? Should it be an interface or another struct ?

答案1

得分: 7

你可以这样做:

type Car interface { IAmACar() }

type MyCarA struct {
  specificToA int
}
func (MyCarA) IAmACar() {}

type MyCarB struct {
  specificToB int
}
func (MyCarB) IAmACar() {}

你可以使用类型断言来测试标记,如下所示:

_, itIsACar := v.(Car)

playground 示例

Car 接口还可以用于静态错误检测:

var c Car
c = MyCarA{0} // 正常
c = 0 // 错误,int 不是 car

go/ast 包也做了类似的事情。可以查看 ast.go 文件中 exprNode 函数的用法。

英文:

You can do this:

type Car interface { IAmACar() }

type MyCarA struct {
  specificToA int
}
func (MyCarA) IAmACar() {}

type MyCarB struct {
  specificToB int
}
func (MyCarB) IAmACar() {}

You test for the marker using a type assertion:

_, itIsACar := v.(Car)

playground example

The Car interface can also be used to detect errors statically:

var c Car
c = MyCarA{0} // ok
c = 0 // error, int is not a car

The go/ast package does something similar. See uses of the function exprNode in the file ast.go.

答案2

得分: 0

上述方法是正确的,并且适用于运行时检测,但它无法提供编译时检测。如果你想要编译时检测,可以将类型传递给一个以接口作为参数的函数,并进行检查。请参考下面的示例代码:

package main

import "fmt"

type MyType struct {
    a int
    b int
}

type NotMyType struct {
    a int
    b int
}

type Printer interface {
    Print(a string) error
}

func (m *MyType) Print(s string) error {
    fmt.Println(m.a, m.b, s)
    return nil
}

//取消下面的函数注释以查看编译工作
// func (m *NotMyType) Print(s string) error {
//     fmt.Println(m.a, m.b, s)
//     return nil
// }

func main() {
    t := &MyType{
        a: 1, b: 2,
    }

    t1 := &NotMyType{
        a: 1, b: 2,
    }

    checkPrintable(t)
    checkPrintable(t1)
}

func checkPrintable(p Printer) {
    p.Print("Test message")
}

要使其工作,你需要取消注释NotMyType的Print函数。

希望对你有所帮助。

英文:

The above method is correct & works for runtime detection, but it won't provide compile time detection. If you want compile time detection, pass the type to a function which takes the interface as an argument and check. See sample below:

package main

import "fmt"

type MyType struct {
	a int
	b int
}

type NotMyType struct {
	a int
	b int
}

type Printer interface {
	Print(a string) error
}

func (m *MyType) Print(s string) error {
	fmt.Println(m.a, m.b, s)
	return nil
}

//Uncomment following function to see compilation work
// func (m *NotMyType) Print(s string) error {
// 	fmt.Println(m.a, m.b, s)
// 	return nil
// }

func main() {
	t := &MyType{
		a: 1, b: 2,
	}

	t1 := &NotMyType{
		a: 1, b: 2,
	}

	checkPrintable(t)
	checkPrintable(t1)
}

func checkPrintable(p Printer) {
	p.Print("Test message")
}

To make it work you need to uncomment the Print function for NotMyType.

Hope this helps.

huangapple
  • 本文由 发表于 2017年6月22日 12:32:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/44690196.html
匿名

发表评论

匿名网友

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

确定