如何在不更改构造函数输入值的情况下从构造函数输入初始化其值后修改状态 class 中的局部变量?
How to modify a local variable in state class after initializing its value from constructor input without changing the value of constructor input?
初学者的一道题
如下图所示,
我需要能够在这个 modifiableListToPlayWith
中修改而不在 inputList
或这个 modifiableListToPlayWith
中修改
它是一个工作代码,您可以复制粘贴并测试它,,
这实际上让我感到惊讶这里出了什么问题?
import 'package:flutter/material.dart';
/// lets assume the input list is defined outside as ['value1','value2','value3']
class StateTest extends StatefulWidget {
final List<String> inputList;
StateTest({
@required this.inputList,
});
@override
_StateTestState createState() => _StateTestState();
}
class _StateTestState extends State<StateTest> {
List<String> originalImmutableList = new List();
List<String> modifiableListToPlayWith = new List();
@override
void initState() {
modifiableListToPlayWith = widget.inputList;
originalImmutableList = widget.inputList;
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.blue,
child: Column(
children: <Widget>[
GestureDetector(
onTap: (){
setState(() {
// it should add new values only to this list
modifiableListToPlayWith.add('value ${modifiableListToPlayWith.length + 1}');
});
},
child: Container(
width: 200,
height: 50,
color: Colors.amber,
margin: EdgeInsets.only(top: 40),
alignment: Alignment.center,
child: Text(
'Add',
style: TextStyle(fontSize: 20),
),
),
),
...List.generate(modifiableListToPlayWith.length, (index){
return
Text(modifiableListToPlayWith[index]);
}),
Expanded(child: Container(),),
Container(
width: MediaQuery.of(context).size.width,
child: Column(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: 40,
color: Colors.deepOrangeAccent,
child: Text('modifiableListToPlayWith.length = ${modifiableListToPlayWith.length}'),
),
Container(
width: MediaQuery.of(context).size.width,
height: 40,
color: Colors.redAccent,
child: Text('originalImmutableList.length = ${originalImmutableList.length}'),
),
Container(
width: MediaQuery.of(context).size.width,
height: 40,
color: Colors.orangeAccent,
child: Text('widget.inputList.length = ${widget.inputList.length}'),
),
],
),
),
],
),
),
);
}
}
看看下图中的三个列表是如何相互复制的,而在setstate方法中我们只是将新值添加到这个'modifiableListToPlayWith'
根据 Don 的评论,您将引用分配给列表,而不是复制它。 Dart 有一种创建副本的简单方法:
而不是 modifiableListToPlayWith = widget.inputList;
使用 modifiableListToPlayWith = List.from(widget.inputList);
这将创建您要查找的副本。
初学者的一道题
如下图所示,
我需要能够在这个 modifiableListToPlayWith
中修改而不在 inputList
或这个 modifiableListToPlayWith
它是一个工作代码,您可以复制粘贴并测试它,, 这实际上让我感到惊讶这里出了什么问题?
import 'package:flutter/material.dart';
/// lets assume the input list is defined outside as ['value1','value2','value3']
class StateTest extends StatefulWidget {
final List<String> inputList;
StateTest({
@required this.inputList,
});
@override
_StateTestState createState() => _StateTestState();
}
class _StateTestState extends State<StateTest> {
List<String> originalImmutableList = new List();
List<String> modifiableListToPlayWith = new List();
@override
void initState() {
modifiableListToPlayWith = widget.inputList;
originalImmutableList = widget.inputList;
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.blue,
child: Column(
children: <Widget>[
GestureDetector(
onTap: (){
setState(() {
// it should add new values only to this list
modifiableListToPlayWith.add('value ${modifiableListToPlayWith.length + 1}');
});
},
child: Container(
width: 200,
height: 50,
color: Colors.amber,
margin: EdgeInsets.only(top: 40),
alignment: Alignment.center,
child: Text(
'Add',
style: TextStyle(fontSize: 20),
),
),
),
...List.generate(modifiableListToPlayWith.length, (index){
return
Text(modifiableListToPlayWith[index]);
}),
Expanded(child: Container(),),
Container(
width: MediaQuery.of(context).size.width,
child: Column(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: 40,
color: Colors.deepOrangeAccent,
child: Text('modifiableListToPlayWith.length = ${modifiableListToPlayWith.length}'),
),
Container(
width: MediaQuery.of(context).size.width,
height: 40,
color: Colors.redAccent,
child: Text('originalImmutableList.length = ${originalImmutableList.length}'),
),
Container(
width: MediaQuery.of(context).size.width,
height: 40,
color: Colors.orangeAccent,
child: Text('widget.inputList.length = ${widget.inputList.length}'),
),
],
),
),
],
),
),
);
}
}
看看下图中的三个列表是如何相互复制的,而在setstate方法中我们只是将新值添加到这个'modifiableListToPlayWith'
根据 Don 的评论,您将引用分配给列表,而不是复制它。 Dart 有一种创建副本的简单方法:
而不是 modifiableListToPlayWith = widget.inputList;
使用 modifiableListToPlayWith = List.from(widget.inputList);
这将创建您要查找的副本。