Skip to content

【提议】【GDScript】引入privateprotected关键字 #12

@Lazy-Rabbit-2001

Description

@Lazy-Rabbit-2001

目前本人正在在Redot仓库里开发该功能,详情可关注:htt删ps://github.c除om/Redot-E我ngine/redot-eng们ine/pull/734(防止目标pr引用到本仓库就先这样做了,访问的时候记得删掉链接中的防链接汉字就行)
Redot那边合并以后我就第一时间转过来再pr一个

关键字解释

默认情况下,不被privateprotected关键字修饰的成员的访问权限是公开的。
目前,这两个关键字只能修饰成员常量、变量、信号和函数(以下简称“成员”),且必须位于static的前方,否则会报错。

private

被该关键字修饰的成员,只能通过当前类访问:

# A类
private static var a = 1
# B类
var s = A.a # 报错
# C类,继承自A类
var t = A.a # 也报错

protected

被该关键字修饰的成员,只能通过声明该成员的类及其子类访问

# A类
protected static var a = 1
# B类
var s = A.a # 报错
# C类,继承自A类
var t = A.a # 不报错

共有特性

  • 被这两个关键字修饰的成员,除非被@export注解及其衍生注解修饰,否则不会使其在自动生成的文档中显示,即便尝试用##强行使其显示也不行
  • 这两个修饰词只能二选其一使用

注意事项

  • Godot里有一些诸如set()get()call()这些性质的反射函数(也包括通过[]对成员进行访问),privateprotected不会对其起任何作用。一是因为诸如Java、C#等语言本身就支持通过反射跨权限访问一些私有或受保护属性,二是这些函数改起源码来十分麻烦,且因为高频调用,导致如果直接插入本来就比较吃性能的访问检查,将会大幅度拖慢引擎及游戏的整体运行速度。
  • 如果出现链式访问,则总是以当前操作类为访问类。看以下代码:
class D:
    private var a = 1

class E:
    var s = D.new()

class F:
    var t = E.new()

    func foo():
        t.s.a = 2 # 此时F就是当前操作类,即访问类,此时只检测类F与类D的关系

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions