Bloki prób transakcyjnych w ValueScript
Apr 02 2023
Wyjątki są trudne do uzyskania. Szczególnie trudnym problemem, który łatwo przeoczyć, jest możliwość częściowej oceny wewnątrz bloków try.
Wyjątki są trudne do uzyskania. Szczególnie trudnym problemem, który łatwo przeoczyć, jest możliwość częściowej oceny wewnątrz trybloków.
Rozważ następujący program JavaScript:
let a = new SmallQueue(["item1"]);
let b = new SmallQueue(["item2", "item3", "item4"]);
try {
const item = a.pop();
b.push(item);
} catch (e) {
console.error("Failed to move item from a to b", e);
}
console.log({ a, b });
{
a: [],
b: ["item2", "item3", "item4", "item1"],
}
{
a: [],
b: ["item2", "item3", "item4"],
}
let a = new SmallQueue(["item1"]);
let b = new SmallQueue(["item2", "item3", "item4"]);
try {
if (b.isFull()) {
throw new Error("b is full");
}
const item = a.pop();
b.push(item);
} catch (e) {
console.error("Failed to move item from a to b", e);
}
console.log({ a, b });
Inną opcją jest zapisanie kopii zmiennych, które mogą ulec zmianie, i przywrócenie ich w dniu catch:
let a = new SmallQueue(["item1"]);
let b = new SmallQueue(["item2", "item3", "item4"]);
const aCopy = a.copy();
const bCopy = b.copy();
try {
const item = a.pop();
b.push(item);
} catch (e) {
a = aCopy;
b = bCopy;
console.error("Failed to move item from a to b", e);
}
console.log({ a, b });
- Możesz tego nie robić, ponieważ jest gadatliwy i wydaje się niepotrzebnie defensywny
- Wymaga
copyzdefiniowania operacji - Jeśli
copyoperacja istnieje, może nie być wydajna - Jeśli
a.popma skutki uboczne, te skutki uboczne nie zostaną cofnięte
let a = new SmallQueue(["item1"]);
let b = new SmallQueue(["item2", "item3", "item4"]);
let item;
try {
item = a.pop();
} catch (e) {
console.error("Failed to move item from a to b", e);
console.log({ a, b });
return;
}
try {
b.push(item);
} catch (e) {
a.unPop(item);
console.error("Failed to move item from a to b", e);
}
console.log({ a, b });
- Niezwykle gadatliwy
a.unPop(item)wymaga od nas zrozumienia, że ta operacja jest potrzebna, gdyb.push(item)się nie powiedzie, co wciąż łatwo przeoczyć
W ValueScript trybloki są transakcyjne — albo są realizowane do końca, albo są cofane.
Nasz autorski program robi to, co chcieliśmy bez żadnych modyfikacji:
let a = new SmallQueue(["item1"]);
let b = new SmallQueue(["item2", "item3", "item4"]);
try {
const item = a.pop();
b.push(item);
} catch (e) {
console.error("Failed to move item from a to b", e);
}
console.log({ a, b });
{
a: ["item1"],
b: ["item2", "item3", "item4"],
}
- „Możesz tego nie zrobić”
— kompilator ValueScript wstawia instrukcje automatycznie - „Wymaga
copyoperacji”
— ValueScript używa semantyki wartości, po prostu używaaCopy = a, co jest równoznaczne z kopiowaniem - „
copymoże nie być wydajny”
— ValueScript używa kopiowania przy zapisie do samego końca, co jest dość wydajne - „Skutki uboczne
a.popnie zostaną cofnięte”
— ValueScript nie ma skutków ubocznych
* niektóre niesamowite funkcje obce mogą obejmować operacje przywracania i byłyby one wywoływane automatycznie
ValueScript to dialekt języka TypeScript z semantyką wartości. Ma internetowy plac zabaw, w tym demonstrację programu z tego artykułu , i jest open source .

![Czym w ogóle jest lista połączona? [Część 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































