d的常量与逻辑常
但只有该例:
struct Foo
{
mutable int len;
mutable bool len_done;
const char* str;
int length()
{
if (!len_done)
{
len = strlen(str);
len_done = true;
}
return len;
}
this(char* str) { this.str = str; }
}
const Foo f = Foo("hello");
bar(f.length);
阿里:
你是对的,const
不是绝对必要的.然而,这是非常有用
概念,甚至有些编程语言
根本禁止变量
.
不可变性
很重要,有些人甚至认为D
中的默认值
应该是不变
的.如rust
等.
我们都同意那篇文章
struct Foo
{
mutable int len;//可变
哇!一定来自D的早期.现在D
中没有"可变"了.
mutable bool len_done;
const char* str;
int length()
{
if (!len_done)
{
len = strlen(str);
len_done = true;
}
该示例
是逻辑常
概念,对象按需
计算一些值,并缓存
供以后使用的结果.即使下面的"f"
对象是const
,也可修改"len"
(和len_done
)成员.但是,该示例不适合今天的D
,因为已标记函数
为"const"
:
int length() const {
// ...
}
D
目前没有逻辑常
,但是,可使用强制转换
,玩一玩.(可能是未定义的行为
等).
}
this(char* str) { this.str = str; }
}
const Foo f = Foo("hello");
bar(f.length);
因此,有f'const'
对象,并调用它的改变对象
的两个成员
的length()
函数.由于这些变量
不会改变对象值
,因此认为对象不变.即,缓存对象
的部分内容
不算更改该对象
.这就是逻辑常
的含义:发生了变化,但并未改变对象状态
.
什么
是逻辑常
?,如何使它有用
?而不仅仅是(如在C++
中)无硬性保证和可验证性
的约定
.
目前,D
有物理常
,因此缓存/懒初化
不能用常
.逻辑常:有变化,但对外不变化
.
但物理常
呢?本质上是由语言保证
并由编译器静态验证
物理数据未变的契约
.表明,在操作前后
,物理数据
未变化.
可扩展
到逻辑常
吗?不保证物理数据不变
,而是保证对象
的*外部可观察行为*
不变的合约
呢?
只要内部
逻辑不变.那么行为
就类似常
.
如,在惰初化
中,应可证明
外部观察到的对象值
不变.外界看不见值未初化
的初态
;仅在初化
后可观察值
,此后不变
.
缓存值
同样:应可证明第一次
计算值是*唯一*
外部可观察值
;初始
计算后,该值不变
.
类似,初化不变
值的构造器
的扩展.编译器跟踪是否已初化变量
,并在构造器
内部给定是否不变
,而外部看不见未初化
值.赋值后,编译器不强制
后续更改.
类似D纯
,只要外界无法区分,就可不纯
操作.
应可实现逻辑常
,在放宽物理不变
时仍提供保证
.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现