Inspect a Go interface with a type switch
Type switches are for imported Go interface values. They preserve Go's dynamic type behavior while giving every case a statically narrowed binding.
Source
ts
import go bytes from "bytes";
import go fmt from "fmt";
import go io from "io";
import go strings from "strings";
function classify(value: io.Reader): bstring {
switch (value) {
case const reader as *strings.Reader {
return "string:" + fmt.Sprint(reader.Len());
}
case const buffer as *bytes.Buffer {
return "buffer:" + fmt.Sprint(buffer.Len());
}
case nil { return "nil"; }
default { return "other"; }
}
}
function main(): void {
const text: io.Reader = strings.NewReader("hello");
const buffer: io.Reader = bytes.NewBufferString("planet");
const empty: io.Reader = nil;
fmt.Println(classify(text));
fmt.Println(classify(buffer));
fmt.Println(classify(empty));
}Run
sh
keika check type-switch.km
keika run type-switch.kmExpected output:
text
string:5
buffer:6
nilContract demonstrated
- The switch subject evaluates once.
case const name as Typecreates a case-local typed binding.- A
nilinterface case is distinct fromdefault. - Types must be possible implementations of the subject interface.
- Duplicate types, duplicate
nil, and duplicatedefaultare rejected. - Type switches never use
fallthrough.
Use let instead of const when the narrowed binding itself must be reassigned, or _ when only the dynamic-type match matters.
For one assertion outside a switch, use const [reader, ok] = value as? *strings.Reader;. Use as! only when assertion failure should panic.
See Go interoperability and Language syntax.