网页资讯视频图片知道文库贴吧地图采购
进入贴吧全吧搜索

 
 
 
日一二三四五六
       
       
       
       
       
       

签到排名:今日本吧第个签到,

本吧因你更精彩,明天继续来努力!

本吧签到人数:0

一键签到
成为超级会员,使用一键签到
一键签到
本月漏签0次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行补签。
连续签到:天  累计签到:天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
01月01日漏签0天
godot吧 关注:9,750贴子:43,034
  • 看贴

  • 图片

  • 吧主推荐

  • 游戏

  • 1 2 下一页 尾页
  • 38回复贴,共2页
  • ,跳到 页  
<<返回godot吧
>0< 加载中...

GDScript小技巧——只读属性

  • 只看楼主
  • 收藏

  • 回复
  • fang_chu
  • 数学算法
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
在进行类属性的封装时,我们希望将某些属性设置为外部只读状态
而GDScript不支持像 C井 那样使用readonly关键字或使用{ get; private set; } 这样的访问器
但是GDScript也提供了getter和setter访问器,于是,就有了以下实现方法


  • fang_chu
  • 数学算法
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

这里定义了两个变量,member供外部访问,使用getter访问器,_member供内部访问
GDScript不具有 C井 那样有访问级别的特性,所有成员都是公开的(public),而即使在命名时加上下划线也不会变成私有的(private)
不过官方是说法是“在用户必须覆盖的虚方法、私有函数、私有变量的名称前加一个下划线(_)”
实际上只是命名规范,并没有真正实现私有就是了(划掉)


2026-01-01 02:45:41
广告
不感兴趣
开通SVIP免广告
  • fang_chu
  • 数学算法
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
这样当外部访问member变量时,实际上是在访问_member变量,这也就导致,即使将member的值设置为true,再次访问时,它的值还是false


  • fang_chu
  • 数学算法
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
虽然说外部也能直接修改_member的值就是了(划掉)


  • fang_chu
  • 数学算法
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

接下来是更严格的访问限制
这里使用了assert关键字,在外部设置member值时,会直接触发断言,而暂停项目


  • fang_chu
  • 数学算法
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
至于为什么使用assert,而不是push_error,和print,因为assert是最醒目的错误输出


  • 神秘海马人
  • GDScript
    5
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
感谢分享


  • fang_chu
  • 数学算法
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
而对于字典(Dictionary)和数组(Array)这样的集合,有专门的方法来实现只读

这里定义了一个member字典,并在类的构造函数中将其设置为只读
而这会使member这个字典达成同2楼一样的效果,无论设置的键值对是多少,返回的始终是定义的常量{"key":10},
Array也是一样的写法
但是这样会变成内部和外部都是只读的


2026-01-01 02:39:41
广告
不感兴趣
开通SVIP免广告
  • fang_chu
  • 数学算法
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

所以,我们可以套用之前的方法,使这个属性仅外部只读,在这里,实现了和make_read_only方法一样的效果,增加了设置值时断言的效果
这样访问值时获取的是"key":1,而不是"key":10,并且还能够通过修改_member变量来更改访问member变量时获取的值,而不是像make_read_only方法那样完全写死


  • fang_chu
  • 数学算法
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

GDScript与 C井 不同的是在getter访问器访问该属性自身时,不会导致getter被无限次递归调用(但是在匿名的getter/setter调用具名的getter/setter时,就会导致无限递归)
所以,在这里,如果删去_member变量,这样也就实现了真正的只读,member属性始终是11,是只读的。(那我还不如定义一个常量(划掉))


  • 五条牢师还在尽力
  • 动画特效
    4
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
挺好的,也可以复写godot object的get method,省去getter这一步


  • 某131
  • GDScript
    5
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
纠正一下8-9楼的小错误
利用setter和getter实现的只读和make_read_only的效果是不一样的哦
make_read_only会使数组/字典对象内的内容无法进行修改,但变量本身是可以重新赋值的
举个例子,一个object对象中分别定义了array和dictionary两个变量,并对这两个字典/数组进行make_read_only后:
object.array[2] = "hello" //不可行。
object.array= ["hello", "world"] //可行。
object.dictionary["hello"] = "world" //不可行。
object.dictionary= {"hello": "world"} //可行。
前面楼主说的测试的时候make_read_only没用,可能也是因为楼主并不是尝试对字典/数组的内容进行修改,而是直接对变量进行赋值


  • 某131
  • GDScript
    5
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
而同样的情况下,利用楼主的setter/getter实现字典/数组变量的只读后的结果:
object.array[2] = "hello" //可行。
object.array= ["hello", "world"] //不可行。
object.dictionary["hello"] = "world" //可行。
object.array= {"hello": "world"} //不可行。
这是因为字典/数组本身并没有调用make_read_only方法,因而它们的内容是可以被修改的。我们通过object.array(get)(dictionary同理)获得了字典/数组的引用,而在这期间我们并没有对字典/数组变量通过赋值(或者别的手段)进行更改,因此不会触发变量的set方法。获取字典/数组的引用后,我们通过调用方法/下标赋值等等对字典/数组内容的修改是可以正常生效的。
而直接对array和dictionary变量进行赋值是不可行的,这一点就是楼主在前面的setter和getter起到的作用


  • 某131
  • GDScript
    5
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
如果想要实现字典/数组及其内容都使外部只读,我们可以采用这种写法:
var array: Array:
get:
return _array.duplicate()
这样在对array进行访问时,返回的是_array的副本,接下来不论怎样进行操作都不会影响到_array本身的内容了。
字典同理。
不过这么搞可能会比较占性能(我猜的)


2026-01-01 02:33:41
广告
不感兴趣
开通SVIP免广告
  • fang_chu
  • 数学算法
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
综合一下12-14楼的说法,对集合的只读其实这样实现就行,这里引用我开源项目的代码
对集合写上getter,然后再在构造函数里make_read_only就行
这样修改引用会失效,修改元素会抛出异常




登录百度账号

扫二维码下载贴吧客户端

下载贴吧APP
看高清直播、视频!
  • 贴吧页面意见反馈
  • 违规贴吧举报反馈通道
  • 贴吧违规信息处理公示
  • 1 2 下一页 尾页
  • 38回复贴,共2页
  • ,跳到 页  
<<返回godot吧
分享到:
©2026 Baidu贴吧协议|隐私政策|吧主制度|意见反馈|网络谣言警示