(Ich bin mir bei Java nicht sicher) Ich dachte, es wäre schön, standardmäßig den direkten Summentyp zu unterstützen. Zusätzlich zum Lernen mit dem direkten Summentyp habe ich einen "Interpreter erstellt, der Formeln in umgekehrter polnischer Notation berechnet (wie" 1 2 + "=" 3 ")".
package neta;
import java.util.Stack;
public class Main {
//Ein Typ, der einen numerischen Typ darstellt
static class IntType extends Exception {
int v;
IntType(int v) {
this.v = v;
}
@Override
public String toString() {
return Integer.toString(v);
}
}
//Ein Typ, der eine positive Operation darstellt
static class PlusOperation extends Exception {
@Override
public String toString() {
return "+";
}
}
private static void eval(String statement) throws IntType, PlusOperation {
try {
throw new IntType(Integer.parseInt(statement));
} catch (NumberFormatException e) {
if (statement.equals("+")) {
throw new PlusOperation();
} else {
//Verwenden Sie Stack, um die umgekehrte polnische Notation zu berechnen
Stack<Integer> stack = new Stack<>();
//Token können durch Leerzeichen getrennt werden
for (String s : statement.split(" ")) {
try {
eval(s);
} catch (IntType iv) {
stack.push(iv.v);
} catch (PlusOperation op) {
stack.push(stack.pop() + stack.pop());
}
}
throw new IntType(stack.pop());
}
}
}
private static void test(String statement) {
try {
eval(statement);
} catch (IntType | PlusOperation e) {
System.out.println(e);
}
}
public static void main(String[] args) {
test("1");
test("1 2 +");
test("3 4 + 5 +");
test("6 7 8 + +");
test("+");
}
}
Wenn ich dieses Programm ausführe, erhalte ich die folgende Ausgabe:
1
3
12
21
+
Es scheint, dass das Schlüsselwort throw
in der Funktionsdefinition verwendet wird, um den Rückgabetyp anzugeben.
//Beispiel
void eval(String statement) throws IntType, PlusOperation
In diesem Beispiel ist der direkte Summentyp von "IntType" und "PlusOperation" der Rückgabetyp der Funktion "eval ()". Es ist cool, den Rückgabetyp nach dem Funktionsnamen zu schreiben, wie in modernen Programmiersprachen (Go / Rust / ..). Ich bin nicht sicher, ob das Schlüsselwort, das eine Funktion darstellt, "void" ist, aber ich denke, es basiert grammatikalisch auf den neuesten Sprachtrends.
Es scheint das Schlüsselwort throw
zu verwenden, wenn ein Wert zurückgegeben wird. Ich denke, viele Programmiersprachen verwenden Schlüsselwörter wie "return", aber das ist selten.
//Beispiel:Gibt einen numerischen Typ zurück
throw new IntType(Integer.parseInt(statement));
//Beispiel:Gibt den Additionsoperator zurück
throw new PlusOperation();
Beachten Sie, dass Sie bei der Rückgabe eines Werts eine Instanz einer Klasse mit einer "erweiterten Ausnahme" wie "IntType" festlegen müssen, da sonst ein Kompilierungsfehler angezeigt wird. Es ist ein wenig mühsam.
Verwenden Sie try / catch
, um die Verzweigung nach Typ zu bedingen. Es ist wie bei Scala oder einem modernen Sprachspiel.
try {
eval(s);
} catch (IntType iv) {
//Verarbeitung nach Typ
} catch (PlusOperation op) {
//Verarbeitung nach Typ
}
In einer Sprache mit einer langen Geschichte scheint ein Besuchermuster verwendet zu werden, oder ein Typ wird überprüft und mit etwas wie "instanceof" verzweigt.
Wie bei der Go-Sprache scheint es zu einem Kompilierungsfehler zu kommen, wenn Sie den zurückgegebenen Fehler nicht überprüfen.
try {
throw new IntType(Integer.parseInt(statement));
} catch (NumberFormatException e) {
//Was tun, wenn ein Fehlertypwert zurückgegeben wird?
}
Oben können Sie die normale Verarbeitung sofort schreiben und müssen den Rückgabewertfehler nicht einzeln überprüfen, sodass er wie eine Monade ist.
Recommended Posts