飞镖中有结构吗?

时间:2014-07-15 15:37:31

标签: dart

在javascript中,我总是困扰着人们使用对象作为{x: 1, y: 2}之类的向量,而不是使用数组[1,2]。数组的访问时间比对象快得多,但是通过索引访问会更加混乱,尤其是在需要大型数组的情况下。我知道dart有固定数组,但有没有办法命名数组的偏移量,就像你在另一种语言中使用struct或tuple / record一样?可能定义枚举/常量?

我想要像

这样的东西
List<int> myVector = new List([x,y]);
myVector.x = 5;

是否有相同或惯用的方法来做到这一点?

5 个答案:

答案 0 :(得分:12)

听起来像是一堂课。

 class MyVector {
   final x;
   final y;
   const MyVector(this.x, this.y);
 }

在运行时创建命名索引结构没有更简单,更有效的方法。为简单起见,您通常可以使用Map,但它不如真正的类有效。

一个类应该与固定长度列表一样有效(时间和内存)。

答案 1 :(得分:5)

对我来说,我看到了两种方法。我会在我看来最好的排序

基于类的方法

这里,方法是将您的需求封装在专用对象

优点:

  • 它的封装
  • 您可以根据需要提出几种访问变量的方法
  • 您可以在不破坏所有内容的情况下扩展功能
  • 我喜欢它:p

缺点

  • 花更多时间来创建课程等。
  • 你真的需要我在职业选手中所说的话吗?
  • 对于js人来说可能很奇怪

示例:

class Vector {
  int x;
  int y;

  static final String X = "x";
  static final String Y = "y";

  Vector({this.x, this.y});
  Vector.fromList(List<int> listOfCoor) {
    this.x = listOfCoor[0];
    this.y = listOfCoor[1];
  }

  // Here i use String, but you can use [int] an redefine static final member
  int operator[](String coor) {
    if (coor == "x") {
      return this.x;
    } else if (coor == "y") {
      return this.y;
    } else {
      // Need to be change by a more adapt exception :)
      throw new Exception("Wrong coor");
    }
  }
}

void main() {
  Vector v = new Vector(x: 5, y: 42);
  Vector v2 = new Vector.fromList([12, 24]);

  print(v.x); // print 5
  print(v["y"]); // print 42
  print(v2.x); // print 12
  print(v2[Vector.Y]); // print 24
}

基于枚举的方法:

你也可以定义一个&#34; enum&#34; (实际上并没有真正实现,但将在未来版本中)将包含&#34;快捷方式&#34;为了你的价值

赞成

  • 更简单实施
  • 更像是你的榜样; p

缺点

  • 不太可扩展
  • 我认为不是很漂亮
  • 不是OOP认为

示例:

class Vector {
  static final int x = 0;
  static final int y = 1;
}

void main() {
  List<int> myVector = new List(2);
  myVector[Vector.x] = 5;
  myVector[Vector.y] = 42;
}

做出选择; p

答案 2 :(得分:3)

这只适用于Dart中的课程。

http://dartbug.com

有一些公开功能请求

答案 3 :(得分:3)

如果您拥有相当大的数据结构,则可以使用"dart:typed_data"作为模型,并为存储的数据提供轻量级视图。这样开销应该是最小的。 例如,如果您需要UX8值的4X4矩阵:

import "dart:typed_data";
import "dart:collection";
import "package:range/range.dart";
class Model4X4Uint8 {
  final Uint8List _data;
  static const int objectLength = 4 * 4;
  final Queue<int> _freeSlotIndexes;
  Model4X4Uint8(int length): _data = new Uint8List((length) * objectLength),
        _freeSlotIndexes = new Queue<int>.from(range(0, length));
  int get slotsLeft => _freeSlotIndexes.length;
  num operator [](int index) => _data[index];
  operator []=(int index, int val) => _data[index] = val;
  int reserveSlot() =>
      slotsLeft > 0 ? _freeSlotIndexes.removeFirst() : throw ("full");
  void delete(int index) => _freeSlotIndexes.addFirst(index);
}
class Matrix4X4Uint8 {
  final int offset;
  final Model4X4Uint8 model;
  const Matrix4X4Uint8(this.model, this.offset);
  num operator [](int index) => model[offset + index];
  operator []=(int index, int val) => model[offset + index] = val;
  void delete() => model.delete(offset);
}
void main() {
  final Model4X4Uint8 data = new Model4X4Uint8(100);
  final Matrix4X4Uint8 mat = new Matrix4X4Uint8(data, data.reserveSlot())
      ..[14] = 10
      ..[12] = 256; //overlow;
  print("${mat[0]} ${mat[4]} ${mat[8]} ${mat[12]} \n"
        "${mat[1]} ${mat[5]} ${mat[9]} ${mat[13]} \n"
        "${mat[2]} ${mat[6]} ${mat[10]} ${mat[14]} \n"
        "${mat[3]} ${mat[7]} ${mat[11]} ${mat[15]} \n");
  mat.delete();
}

但这是一个非常低级别的解决方案,可以轻松地创建内存管理和溢出的漏洞。

答案 4 :(得分:0)

您还可以在extension上使用List来创建特定索引的别名。

虽然很难设置互斥别名,但在某些情况下,这可能是一个简单的解决方案。

import 'package:test/test.dart';

extension Coordinates<V> on List<V> {
  V get x => this[0];

  V get y => this[1];

  V get z => this[2];
}

void main() {
  test('access by property', () {
    var position = [5, 4, -2];
    expect(position.x, 5);
    expect(position.y, 4);
    expect(position.z, -2);
  });
}