我在将元素添加到保留通用类型值集合的对象时遇到麻烦。我尝试了导致错误的最小工作示例:
class ImageTile extends StatelessWidget {
final ImageLessonData imageLessonData;
final String collection;
static int tappedGestureDetector = 0; // <-- replaced 'tapped' and 'other'
ImageTile(this.imageLessonData, this.collection);
@override
Widget build(BuildContext context) {
return Material(
child: GestureDetector(
child: FutureBuilder<QuerySnapshot>(
future: Firestore.instance.collection("images-lessons").document("images").collection(collection).getDocuments(),
builder: (context, snapshot){
if(!snapshot.hasData){
return Center(child: CircularProgressIndicator(),);
}
else {
return GridView.count(
crossAxisCount: 1,
children: snapshot.data.documents.map((doc){
return GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
children: <Widget>[
GestureDetector(
onTap: (){
setState(() { tappedGestureDetector = 0; }); // <-- replaced 'tapped' and 'other'
},
child: Container(
decoration: BoxDecoration(border: tappedGestureDetector == 0 ? Border.all(color: Colors.black, width: 1.0) : Border.all(color: Colors.transparent,),),
child: Image.network(doc.data["imageL"][0],),
),
),
GestureDetector(
onTap: (){
setState(() { tappedGestureDetector = 1; }); // <-- replaced 'tapped' and 'other'
},
child: Container(
decoration: BoxDecoration(border: tappedGestureDetector == 1 ? Border.all(color: Colors.black, width: 1.0) : Border.all(color: Colors.transparent,),),
child: Image.network(doc.data["imageL"][1],),
),
),
GestureDetector(
onTap: (){
setState(() { tappedGestureDetector = 2; }); // <-- replaced 'tapped' and 'other'
},
child: Container(
decoration: BoxDecoration(border: tappedGestureDetector == 2 ? Border.all(color: Colors.black, width: 1.0) : Border.all(color: Colors.transparent,),),
child: Image.network(doc.data["imageL"][2],),
),
),
GestureDetector(
onTap: (){
setState(() { tappedGestureDetector = 3; }); // <-- replaced 'tapped' and 'other'
},
child: Container(
decoration: BoxDecoration(border: tappedGestureDetector == 3 ? Border.all(color: Colors.black, width: 1.0) : Border.all(color: Colors.transparent,),),
child: Image.network(doc.data["imageL"][3],),
),
),
],
);
}).toList() ,);
}
}),
),
);
}
}
当我尝试编译所有这些内容时,出现错误:
class OneElementQueue {
type eltType;
var elements : [0..0] eltType;
//initializer
proc init(type eltType) {
this.eltType = eltType;
}
proc add(element : eltType) {
this.elements[0] = element;
}
proc remove() : eltType {
return this.elements[0];
}
} //end of OneElementQueue
class Monkey {
var name: string;
var age: int;
proc init(name : string, age : int) {
this.name = name;
this.age = age;
}
} //end of class Monkey
var q = new owned OneElementQueue(Monkey);
var m = new owned Monkey("Kyle", 6);
q.add(m);
向这样的通用数据结构添加内容的正确方法是什么?我该怎么办呢?
答案 0 :(得分:3)
这里有两种可能的方法,具体取决于您想要的行为:
“我想让我的收藏集获得Monkey对象的所有权”
在这种情况下,您需要实例化OneElementQueue
集合以存储owned Monkey
对象,而不是简单地存储[borrowed] Monkey
对象,这是类类型的默认设置。您可以通过一行更改(Try it Online)来做到这一点:
var q = new owned OneElementQueue(owned Monkey);
在这种方法中,将owned Monkey
传递给您的add()
方法会将所有权传递给参数,并最终传递给集合,从而使原始对象引用无效(nil
)。 / p>
“我想让我的收藏借用现有的Monkey对象而不占有它们的所有权”
在这种情况下,您需要告诉add()
方法,传递给它的参数将超过参数本身的寿命(然后确保不要撒谎)。在教堂版本1.19中,这可以通过生命周期注释来完成:
proc add(element : eltType) lifetime element > this {
其中注释lifetime element > this
声明通过element
传递的实际参数将比this
集合本身更有效,因此编译器不必担心一旦正式形式借用就不再存在。有争论。
终身注释在教堂1.18中不可用,因此,如果您使用的是该版本,则需要使用稍大的锤子并将pragma "unsafe"
应用于该方法。请注意,编译指示不是官方支持的功能,并且将来可能会更改,因此,在这种情况下,直到实现了生命周期注释,(Try it Online)都是一个权宜之计:
pragma "unsafe"
proc add(element : eltType) {