Godot 学习记录: 与 Unity, UE 完全不同的结构思路

知识点

动态语言与鸭子类型

官方文档

C#也算作动态语言. 与C++, java等静态语言有几个很值得注意的不同:

  • 一些在静态语言编译时能够检查出来的错误, 在动态语言中无法检测出来. 只会在运行的时候报错
  • 动态语言, 包括C#和GDScript, 默认对基础类型的传递是值传递, 默认对其他所有类型是引用传递.

鸭子类型可以视为静态语言的简化和解耦. 对象A调用对象B的某个方法时, 无需检测复杂的继承关系是否使对象B实现了该方法, 会直接尝试调用.

“当我看到一只鸟像鸭子一样走路, 像鸭子一样游泳, 像鸭子一样呱呱叫时, 我就管这只鸟叫鸭子”

但是如果对象B实际上没有实现该方法的话, 程序就会在运行时报错. 按照之前写Unity的经验, 可以举例: 如果某个游戏对象上的脚本尝试获取一个游戏对象上不存在的组件时, 就会报错. 如果再尝试进一步调用组件的方法, 甚至可能会结束程序.

因此, 一般在调用前用如下代码检查是否存在该方法, 再进行调用.

1
2
3
func _on_object_hit(object):
if object.has_method("smash"):
object.smash()

安全行

Gpdot提供了这个工具来在编写代码时告诉程序员, 某行歧义代码是否能正常执行.

1
2
3
$Timer.start()
# => 安全
($Timer as Timer).start()

里氏代换原则 协变与逆变

派生类(子类)对象可以在程序中代替其基类(超类)对象.

要达到这个原则, 简单来说, 子类的输出包含的数据只能比基类更多, 子类能接收的输入只能比基类更宽泛.

协变: 继承方法时, 你可以为子类方法指定一个比该子类方法的父类方法更为具体的返回值类型(子类型). 这保证了子类的输出包含原有输出的所有数据, 只会更多.

逆变: 继承方法时, 你可以为子类方法指定一个比该子类方法的父类方法更不具体的参数类型(超类型). 这保证了子类能够接收原来传给基类的所有数据, 只会能接收更多种.

一句话小技巧

  • 可以用:=来使左边的变量自动推导类型, 达到静态编程的效果.
  • 可以用as xxx来转换返回值类型.
  • Array,

Godot 学习记录: 与 Unity, UE 完全不同的结构思路

http://www.kers.site/2025/06/01/learn-godot/

作者

ker0123

发布于

2025-06-02

更新于

2025-06-14

许可协议

You need to set install_url to use ShareThis. Please set it in _config.yml.
You forgot to set the business or currency_code for Paypal. Please set it in _config.yml.

评论