# 代码片段

使用常见语法和模式的小型、可复制粘贴的 AssemblyScript 示例。

#

一个关于使用类、实例化类及其静态属性的 AssemblyScript 代码片段。

#!runtime=stub
class Animal<T> {
  static ONE: i32 = 1;
  static add(a: i32, b: i32): i32 { return a + b + Animal.ONE; }

  two: i16 = 2; // 6
  instanceSub<T>(a: T, b: T): T { return a - b + <T>Animal.ONE; } // tsc does not allow this
}

export function staticOne(): i32 {
  return Animal.ONE;
}

export function staticAdd(a: i32, b: i32): i32 {
  return Animal.add(a, b);
}

export function instanceTwo(): i32 {
  let animal = new Animal<i32>();
  return animal.two;
}

export function instanceSub(a: f32, b: f32): f32 {
  let animal = new Animal<f32>();
  return animal.instanceSub<f32>(a, b);
}


#!html
<script type="module">
const log = console.log;
console.log = (...args) => {
  log(...args);
  let str = '';
  args.forEach(arg => {
    if (typeof arg == 'object') {
      str += `${JSON.stringify(arg, null, 2)}<br/>`;
    } else {
      str += `${arg}<br/>`;
    }
  });
  document.body.innerHTML += `<div>Log: ${str}</div>`;
}

const exports = await instantiate(await compile(), { /* imports */ });

console.log(exports.staticOne());
console.log(exports.staticAdd(1, 2));
console.log(exports.instanceTwo());
console.log(exports.instanceSub(3.0, 1.0));
</script>

# 扩展类

扩展类和 AssemblyScript 中的一般面向对象编程 (OOP)

#!runtime=stub

class BaseClass {
  static staticProp: i32 = 24;
  instanceProp: i32;

  constructor(value: i32) {
    this.instanceProp = value;
  }

  add(a: i32, b: i32): i32 {
    return a + b;
  }
}

class ExtendedClass extends BaseClass {

  extendedProp: i32;

  constructor(extendedValue: i32) {
    super(1);

    this.extendedProp = extendedValue;
  }

  add(a: i32): i32 {
    return super.add(a, this.extendedProp + super.instanceProp);
  }
}

export function getStaticProp(): i32 {
  return ExtendedClass.staticProp;
}

export function overloadAdd(value: i32): i32 {
  let extendedClass = new ExtendedClass(value);
  return extendedClass.add(24);
}

#!html
<script type="module">
const log = console.log;
console.log = (...args) => {
  log(...args);
  let str = '';
  args.forEach(arg => {
    if (typeof arg === 'object') {
      str += `${JSON.stringify(arg, null, 2)}<br/>`;
    } else {
      str += `${arg}<br/>`;
    }
  });
  document.body.innerHTML += `<div>Log: ${str}</div>`;
}

const exports = await instantiate(await compile(), { /* imports */ });

console.log(`getStaticProp: ${exports.getStaticProp()}`);
console.log(`overloadAdd: ${exports.overloadAdd(24)}`);
</script>

# 处理空值

将空值作为可选返回值的联合类型进行处理,并在 AssemblyScript 中模拟 try/catch 以处理错误。

#!runtime=stub
class MyValue {
  value: i32;

  constructor(value: i32) {
    this.value = value;
  }
}

// Using a class type here, as some types are not nullable
function getMyValue(isAble: boolean): MyValue | null {
  let myValue = new MyValue(24);
  if (isAble) {
    return myValue;
  } else {
    return null;
  }
}

export function positiveAddWithMyValue(a: i32): i32 {
  let myValue = getMyValue(a > 0);
  if (myValue == null) {
    return -1;
  } else {
    return a + myValue.value;
  }
}

#!html
<script type="module">
const log = console.log;
console.log = (...args) => {
  log(...args);
  let str = '';
  args.forEach(arg => {
    if (typeof arg == 'object') {
      str += `${JSON.stringify(arg, null, 2)}<br/>`;
    } else {
      str += `${arg}<br/>`;
    }
  });
  document.body.innerHTML += `<div>Log: ${str}</div>`;
}

const exports = await instantiate(await compile(), { /* imports */ });

if (exports.positiveAddWithMyValue(24) > -1) {
  console.log("Add was successful")
} else {
  console.log("Could not add 24");
}

if (exports.positiveAddWithMyValue(-1) > -1) {
  console.log("Add was successful")
} else {
  console.log("Could not add -1");
}
</script>

# switch case

在 AssemblyScript 中使用 switch case 语句。

注意

目前,switch 条件 (case 值) 隐式转换为 u32,即不支持对字符串或类似内容进行 switch 操作。

#!runtime=stub
export function switchSurprise(a: i32): i32 {
  let response = -1;

  // Using a mix of braces and not using braces
  // to show that both syntaxes are supported here.
  switch (a) {
    case 1:
      response = 100;
      break;
    case 2: {   // Cases can also use braces
      response = 200;
      break;
    }
    case 3:
      // Fall Through to the next case
    case 4:
      response = 400;
      break;
    default: {
      response = 0;
    }
  }

  return response;
}

#!html
<script type="module">
const log = console.log;
console.log = (...args) => {
  log(...args);
  let str = '';
  args.forEach(arg => {
    if (typeof arg == 'object') {
      str += `${JSON.stringify(arg, null, 2)}<br/>`;
    } else {
      str += `${arg}<br/>`;
    }
  });
  document.body.innerHTML += `<div>Log: ${str}</div>`;
}

const exports = await instantiate(await compile(), { /* imports */ });

console.log(`switchSurprise(1) : ${exports.switchSurprise(1)}`);
console.log(`switchSurprise(2) : ${exports.switchSurprise(2)}`);
console.log(`switchSurprise(3) : ${exports.switchSurprise(3)}`);
console.log(`switchSurprise(4) : ${exports.switchSurprise(4)}`);
console.log(`switchSurprise(57) : ${exports.switchSurprise(57)}`);
</script>

# 三元 if-else

在 AssemblyScript 中使用三元 if-else。

#!runtime=stub
export function isTrue(a: i32): i32 {
  let response = a > 0 ? 1 : 0;
  return response;
}

#!html
<script type="module">
const log = console.log;
console.log = (...args) => {
  log(...args);
  let str = '';
  args.forEach(arg => {
    if (typeof arg == 'object') {
      str += `${JSON.stringify(arg, null, 2)}<br/>`;
    } else {
      str += `${arg}<br/>`;
    }
  });
  document.body.innerHTML += `<div>Log: ${str}</div>`;
}

const exports = await instantiate(await compile(), { /* imports */ });

console.log(`is 24 greater than 0? ${exports.isTrue(24) > 0 ? true : false}`);
console.log(`is -3 greater than 0? ${exports.isTrue(-3) > 0 ? true : false}`);
</script>