由于范围原因,不允许向类中的通用集合添加值

时间:2019-03-01 00:50:44

标签: parallel-processing hpc chapel

我在将元素添加到保留通用类型值集合的对象时遇到麻烦。我尝试了导致错误的最小工作示例:

  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);

向这样的通用数据结构添加内容的正确方法是什么?我该怎么办呢?

1 个答案:

答案 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) {