In Isolates, I can refer to a local variable from an outer scope or a field variable of a class without passing it as a separate message.
Is this implicitly copying the values into the new isolation's memory area?
I'm curious about the details.
Example
class Person {
Person(this._baseNum);
/// access [_baseNum] in isolate
final int _baseNum;
int age = 0;
/// access [extraAge] in isolate
Future<void> addAge(int extraAge) async {
final mainReceivePort = ReceivePort();
await Isolate.spawn((SendPort sendPort) async {
sendPort.send(await _calcAge(_baseNum, extraAge));
}, mainReceivePort.sendPort);
age = await mainReceivePort.first;
mainReceivePort.close();
}
static Future<int> _calcAge(int someNum, int age) async {
// ... heavy work ...
return age someNum;
}
}
// ...
void main() {
test('test', () async {
final p = Person(10);
await p.addAge(3);
expect(p.age, 13);
});
}
CodePudding user response:
In Isolates, I can refer to a local variable from an outer scope or a field variable of a class without passing it as a separate message.
Is this implicitly copying the values into the new isolation's memory area?
Yes it is.
One way to demonstrate this is if you take one of these variables from an outer scope or field variable, and update the value within the isolate. What you will see is that from outside the isolate, the value will not be updated. This is because they are working with independent copies of the variable.
import 'dart:isolate';
import 'package:test/test.dart';
class Person {
Person(this._baseNum);
/// access [_baseNum] in isolate
int _baseNum;
int age = 0;
/// access [extraAge] in isolate
Future<void> addAge(int extraAge) async {
final mainReceivePort = ReceivePort();
await Isolate.spawn((SendPort sendPort) async {
_baseNum ; // modify _baseNum
sendPort.send(await _calcAge(_baseNum, extraAge));
}, mainReceivePort.sendPort);
age = await mainReceivePort.first;
mainReceivePort.close();
}
static Future<int> _calcAge(int someNum, int age) async {
// ... heavy work ...
return age someNum;
}
}
// ...
void main() {
test('test', () async {
final p = Person(10);
await p.addAge(3);
expect(p.age, 14);
expect(p._baseNum, 10); // _baseNum still 10 despite _baseNum in isolate
});
}