Ballerina:隔离函数中无法访问只读类属性的问题及解决方法
关于Ballerina中readonly类self实例被判定可变的编译错误问题
我定义了两个相互关联的服务类Astronaut和Mission,并尝试将它们设置为isolated(隔离)状态,但出现了编译错误:
invalid access of mutable storage in an 'isolated' function
我的疑问:readonly class Astronaut的self实例为何会被判定为可变?针对该情况是否有可行的解决方法?
以下是我的代码:
distinct isolated service readonly class Mission { public final int id; private final string designation; private final string? startDate; private final string? endDate; private final readonly & int[] crewIds; isolated function init(int id, string designation, string? startDate, string? endDate, readonly & int[] crewIds) { self.id = id; self.designation = designation; self.startDate = startDate; self.endDate = endDate; self.crewIds = crewIds; } isolated resource function get id() returns int { return self.id; } isolated resource function get designation() returns string { return self.designation; } isolated resource function get startDate() returns string? { return self.startDate; } isolated resource function get endDate() returns string? { return self.endDate; } isolated resource function get crew() returns Astronaut[] { return self.crewIds.map(isolated function(int id) returns Astronaut { return new (id); }); } public isolated function includes(int id) returns boolean { return self.crewIds.indexOf(id) != (); } } distinct isolated service readonly class Astronaut { private final int id; isolated function init(int id) { self.id = id; } isolated resource function get id() returns int { return self.id; } isolated resource function get missions() returns Mission[] { return missions.filter(isolated function(Mission mission) returns boolean { return mission.includes(self.id); // <=============== 引发编译错误的行 }); } } final readonly & Mission[] missions = [ new Mission(1, "Apollo 1", (), (), [14, 30, 7]), new Mission(2, "Apollo 4", "1967-11-09T12:00:01.000Z", "1967-11-09T20:37:00.000Z", []) ];
问题原因
Ballerina的isolated函数对捕获的变量有严格要求:必须是不可变且可安全共享的。虽然Astronaut是readonly类,但self作为实例的引用本身,在isolated lambda函数中被捕获时,编译器无法静态保证这个引用不会被其他并发操作修改——即使类的字段都是不可变的,引用本身的可变性依然会被编译器纳入检查范围,因此self被判定为"可变存储",违反了isolated函数的规则。
解决方法
方案:提取不可变字段到局部final变量
将self.id提取到一个局部的final变量中,这个变量是完全不可变的,符合isolated lambda对捕获变量的要求,你已经采用了这个正确的解决方式:
isolated resource function get missions() returns Mission[] { final int id = self.id; return missions.filter(isolated function(Mission mission) returns boolean { return mission.includes(id); }); }
这种方式的核心是把需要在lambda中使用的不可变值从self实例中剥离出来,转换成一个孤立的不可变变量,让编译器明确确认该变量不会被并发修改,从而通过isolated函数的合规性检查。
内容的提问来源于stack exchange,提问作者Mohamed Ishad
相关产品推荐
相关产品推荐

