Golang接口中的多种方法支持

Golang接口中的多种方法支持 为什么我无法在Go接口中声明具有不同参数的多个方法?我认为这是一个重要的特性。我下面的代码出错了。是我的实现方式有误,还是有其他方法可以实现?如果能获得相关的编码建议也会很有帮助。

package main

import (
	"fmt"
)

type person struct {
}

type human interface {
	speak()
	speak(s string)
}

func (p person) speak() {
	fmt.Println("I have no words to say !!!")
}

func (p person) speak(word string) {
	fmt.Println("I have my words: ", word)
}

func saySomething(h human) {
	h.speak()
	h.speak("I am man.")
}

func main() {

	var p person

	saySomething(p)
}

在像C#这样的面向对象语言中,以下代码是有效的。

using System;

namespace Example5
{
    interface IHuman
    {
        void speak();
        void speak(string word);
    }

    public class Man: IHuman
    {
        public void speak()
        {
            Console.WriteLine("I have no words to say!!!");
        }

        public void speak(string words)
        {
            Console.WriteLine("I have my words: {0}", words);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Man m = new Man();

            m.speak();
            m.speak("I am a man.");
        }
    }
}

更多关于Golang接口中的多种方法支持的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

Go语言不支持方法重载:https://golang.org/doc/faq#overloading

我认为更推荐的风格是编写具有不同名称的方法,例如:

type human interface {
	speak()
	speakString(s string)
}

你可以使用可变参数函数:https://golangdocs.com/variadic-functions-in-golang

type human interface {
    speak(args ...string)
}

更多关于Golang接口中的多种方法支持的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,接口不支持方法重载(overloading)。接口中的每个方法必须有唯一的名称,不能仅通过参数类型或数量来区分。这是Go语言设计上的一个明确选择,旨在保持语言的简洁性和明确性。

在你的代码中,human接口试图声明两个同名的speak方法,这是不允许的。编译器会报错:method speak already declared

要实现类似功能,可以采用以下两种方式:

方案一:使用不同方法名

package main

import "fmt"

type person struct{}

type human interface {
    speak()
    speakWithWord(word string)
}

func (p person) speak() {
    fmt.Println("I have no words to say !!!")
}

func (p person) speakWithWord(word string) {
    fmt.Println("I have my words:", word)
}

func saySomething(h human) {
    h.speak()
    h.speakWithWord("I am man.")
}

func main() {
    var p person
    saySomething(p)
}

方案二:使用可变参数或可选参数模式

package main

import "fmt"

type person struct{}

type human interface {
    speak(words ...string)
}

func (p person) speak(words ...string) {
    if len(words) == 0 {
        fmt.Println("I have no words to say !!!")
        return
    }
    fmt.Println("I have my words:", words[0])
}

func saySomething(h human) {
    h.speak()
    h.speak("I am man.")
}

func main() {
    var p person
    saySomething(p)
}

方案三:使用结构体参数包装

package main

import "fmt"

type SpeakOptions struct {
    Word string
}

type person struct{}

type human interface {
    speak(opt *SpeakOptions)
}

func (p person) speak(opt *SpeakOptions) {
    if opt == nil || opt.Word == "" {
        fmt.Println("I have no words to say !!!")
        return
    }
    fmt.Println("I have my words:", opt.Word)
}

func saySomething(h human) {
    h.speak(nil)
    h.speak(&SpeakOptions{Word: "I am man."})
}

func main() {
    var p person
    saySomething(p)
}

Go语言的设计哲学强调显式优于隐式,因此不支持方法重载。上述方案都能在保持接口方法唯一性的前提下,实现类似的功能需求。

回到顶部