go vs C#/c/c++

发布于:2025-06-28 ⋅ 阅读:(19) ⋅ 点赞:(0)

1. main 函数定义

  • Go
    func main()
    ,不能带参数,也不能有返回值。
  • C/C++
    int main(int argc, char* argv[])
    ,参数可以直接获取命令行参数。
  • C#
    static void Main(string[] args)
    ,参数直接是命令行参数数组。

2. 包和导入(import/using/include)

  • Go:用 
    package
     声明包名,
    import
     导入包。没有头文件,所有导出符号靠首字母大写。
  • C/C++:用 
    #include
     包含头文件,头文件和实现分离,符号导出靠 
    public
    /
    extern
  • C#:用 
    namespace
     和 
    using
    ,一切都在类和命名空间里。

3. 变量声明和初始化

  • Go:类型在后,支持类型推断。
     

    go

     

    var x int = 10
    y := 20 // 自动推断类型

  • C/C++/C#:类型在前,C# 也支持 
    var
     推断。
     

    c

     

    int x = 10;
    int y = 20;

     

    csharp

     

    var y = 20;



4. 指针和内存管理

  • Go:有指针,但没有指针运算,没有 
    *p++
     这种写法。自动垃圾回收,无需手动 free。
  • C/C++:有指针和指针运算,需要手动管理内存(malloc/free, new/delete)。
  • C#:有引用和指针(unsafe),自动垃圾回收。

5. 类、结构体和方法

  • Go:没有类(class),有结构体(struct),可以给 struct 定义方法(func (t *Type) Method())。
  • C++/C#:有类和结构体,支持继承和多态。
  • C:只有 struct,没有方法。

6. 继承与接口

  • Go:没有类继承,只有接口(interface),接口是隐式实现(只要实现了接口的方法就算实现了接口)。
  • C++/C#:有显式继承和接口(C#),C++ 有虚继承和多重继承。

7. 错误处理

  • Go:没有异常(exception),用多返回值 
    return value, err
    ,需要手动判断错误。
  • C++/C#:有 try-catch 异常机制。
  • C:一般用返回值或 errno。

8. 并发模型

  • Go:内置 goroutine 和 channel,非常容易写并发代码。
     

    go

     

    go func() { ... }()

  • C++/C#:用线程库(std::thread, Task, Thread),语法更复杂。

9. 访问控制

  • Go:没有 public/private 关键字。首字母大写即导出,小写即包内可见。
  • C++/C#:有 public/protected/private。

10. 工程结构

  • Go:推荐每个目录一个包,文件可以很多,但包名要统一。
  • C++/C#:通常一个类一个文件,头文件和实现分离(C++),C# 全部在类和命名空间里。

11. 依赖管理

  • Go:用 go.mod 管理依赖,自动下载。
  • C++:用 make/cmake、vcpkg、conan 等。
  • C#:用 NuGet。

12. 编译和部署

  • Go:编译出一个静态二进制文件,部署非常简单。
  • C++/C#:可能有动态库依赖,部署更复杂。

1. 多重继承

Go 语言没有类的多重继承,但可以通过多重组合和接口实现类似效果。

示例:多重组合


go


type Flyer interface {
Fly()
}
type Swimmer interface {
Swim()
}

type Duck struct{}
func (d Duck) Fly() { fmt.Println("Duck flying") }
func (d Duck) Swim() { fmt.Println("Duck swimming") }

func main() {
var f Flyer = Duck{}
var s Swimmer = Duck{}
f.Fly()
s.Swim()
}

你还可以通过 struct 组合多个“父类”:


go


type Animal struct{}
func (a Animal) Eat() { fmt.Println("eat") }

type Flyer struct{}
func (f Flyer) Fly() { fmt.Println("fly") }

type Swimmer struct{}
func (s Swimmer) Swim() { fmt.Println("swim") }

type SuperDuck struct {
Animal
Flyer
Swimmer
}

func main() {
d := SuperDuck{}
d.Eat()
d.Fly()
d.Swim()
}

这样 

SuperDuck

 就“拥有”了 Animal、Flyer、Swimmer 的所有方法,类似多重继承。


2. 虚方法(多态/重写)

Go 没有 virtual 关键字,但通过接口和方法重写实现多态。

示例:接口多态


go


type Animal interface {
Speak()
}

type Dog struct{}
func (d Dog) Speak() { fmt.Println("Woof") }

type Cat struct{}
func (c Cat) Speak() { fmt.Println("Meow") }

func makeItSpeak(a Animal) {
a.Speak()
}

func main() {
makeItSpeak(Dog{})
makeItSpeak(Cat{})
}

示例:组合和“重写”

如果组合 struct 后,子 struct 定义了同名方法,会“覆盖”父 struct 的方法(但不是严格的重写,只是隐藏)。


go


type Animal struct{}
func (a Animal) Speak() { fmt.Println("Animal sound") }

type Dog struct {
Animal
}
func (d Dog) Speak() { fmt.Println("Dog bark") }

func main() {
d := Dog{}
d.Speak() // Dog bark
d.Animal.Speak() // Animal sound
}


3. 总结

  • 多重继承:用组合(嵌入多个 struct)和接口实现,方法名不冲突时全部可用。
  • 虚方法/重写:用接口实现多态,用组合+同名方法实现“隐藏”。
  • 接口:Go 的接口是实现多态的核心,鸭子类型,灵活且强大。

如果你有具体的 C#/C++ 复杂继承场景,想看 Go 里的实现方式,可以举例,我帮你写出 Go 代码对比!


网站公告

今日签到

点亮在社区的每一天
去签到