使用 char
類型
#[wasm_bindgen]
巨集會將 rust 的 char
類型轉換為單個程式碼點的 js string
,此範例顯示如何使用它。
開啟此範例應該會顯示一個單一計數器,其 key
為隨機字元,而其 count
為 0。您可以點擊 +
按鈕來增加計數器的計數。透過點擊「新增計數器」按鈕,您應該會看到一個新的計數器被新增到列表中,其 key
為不同的隨機字元。
在底層,javascript 是從字元陣列中選擇一個隨機字元,並將其傳遞給 rust Counter 結構的建構子,因此您在頁面上看到的字元已完成從 js 到 rust 再返回 js 的完整旅程。
src/lib.rs
#![allow(unused)] fn main() { use wasm_bindgen::prelude::*; // lifted from the `console_log` example #[wasm_bindgen] extern "C" { #[wasm_bindgen(js_namespace = console)] fn log(s: &str); } #[wasm_bindgen] #[derive(Debug)] pub struct Counter { key: char, count: i32, } #[wasm_bindgen] impl Counter { pub fn new(key: char, count: i32) -> Counter { log(&format!("Counter::new({}, {})", key, count)); Counter { key, count } } pub fn key(&self) -> char { log("Counter.key()"); self.key } pub fn count(&self) -> i32 { log("Counter.count"); self.count } pub fn increment(&mut self) { log("Counter.increment"); self.count += 1; } pub fn update_key(&mut self, key: char) { self.key = key; } } }
index.js
/* eslint-disable no-unused-vars */
import { chars } from './chars-list.js';
let imp = import('./pkg');
let mod;
let counters = [];
imp
.then(wasm => {
mod = wasm;
addCounter();
let b = document.getElementById('add-counter');
if (!b) throw new Error('Unable to find #add-counter');
b.addEventListener('click', ev => addCounter());
})
.catch(console.error);
function addCounter() {
let ctr = mod.Counter.new(randomChar(), 0);
counters.push(ctr);
update();
}
function update() {
let container = document.getElementById('container');
if (!container) throw new Error('Unable to find #container in dom');
while (container.hasChildNodes()) {
if (container.lastChild.id == 'add-counter') break;
container.removeChild(container.lastChild);
}
for (var i = 0; i < counters.length; i++) {
let counter = counters[i];
container.appendChild(newCounter(counter.key(), counter.count(), ev => {
counter.increment();
update();
}));
}
}
function randomChar() {
console.log('randomChar');
let idx = Math.floor(Math.random() * (chars.length - 1));
console.log('index', idx);
let ret = chars.splice(idx, 1)[0];
console.log('char', ret);
return ret;
}
function newCounter(key, value, cb) {
let container = document.createElement('div');
container.setAttribute('class', 'counter');
let title = document.createElement('h1');
title.appendChild(document.createTextNode('Counter ' + key));
container.appendChild(title);
container.appendChild(newField('Count', value));
let plus = document.createElement('button');
plus.setAttribute('type', 'button');
plus.setAttribute('class', 'plus-button');
plus.appendChild(document.createTextNode('+'));
plus.addEventListener('click', cb);
container.appendChild(plus);
return container;
}
function newField(key, value) {
let ret = document.createElement('div');
ret.setAttribute('class', 'field');
let name = document.createElement('span');
name.setAttribute('class', 'name');
name.appendChild(document.createTextNode(key));
ret.appendChild(name);
let val = document.createElement('span');
val.setAttribute('class', 'value');
val.appendChild(document.createTextNode(value));
ret.appendChild(val);
return ret;
}