https://github.com/aisk/mygo
なんで……なんで「?」演算子、入れたの!?
https://github.com/aisk/mygo
go
Last synced: 1 day ago
JSON representation
なんで……なんで「?」演算子、入れたの!?
- Host: GitHub
- URL: https://github.com/aisk/mygo
- Owner: aisk
- License: mit
- Created: 2025-06-30T14:28:06.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2026-07-05T16:39:16.000Z (19 days ago)
- Last Synced: 2026-07-05T17:14:26.354Z (19 days ago)
- Topics: go
- Language: Go
- Homepage:
- Size: 308 KB
- Stars: 9
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# mygo

mygo is an experimental *toy* Go preprocessor/transpiler that adds a `?` operator for concise error handling.
For example, `mygo` transforms this:
```go
s := hello()?
```
into standard Go:
```go
s, err := hello()
if err != nil {
return err
}
```
You can also provide a custom error handler block after `?`:
```go
s := hello()? {
return fmt.Errorf("hello failed: %w", err)
}
```
which becomes:
```go
s, err := hello()
if err != nil {
return fmt.Errorf("hello failed: %w", err)
}
```
## Installation
```sh
$ go install github.com/aisk/mygo@latest
```
## Usage
Create `hello.mygo`:
```go
package main
import (
"io"
"os"
)
func hello() error {
f := os.Open("hello.mygo")?
defer f.Close()
s := io.ReadAll(f)?
println(string(s))
return nil
}
func main() {
hello()
}
```
`mygo` supports multiple ways to specify transpile targets:
```sh
$ cat hello.mygo | mygo > hello.go
$ mygo hello.mygo
$ mygo .
$ mygo ./...
$ mygo ...
```
### Integrating with `go generate`
You can keep `.mygo` files as the editable source and generate `.go` files before normal Go builds:
```go
// generate.go
package main
//go:generate mygo hello.mygo
```
Then run:
```sh
$ go generate ./...
$ go test ./...
```
For multiple files or packages, point the directive at a directory:
```go
//go:generate mygo .
//go:generate mygo ./...
```
## Why
mygo tries to add syntax sugar without adding runtime lock-in. The generated files are plain Go code:
- no runtime dependency
- no special library
- no custom Go compiler
## Constraints
To keep the generated Go readable, mygo intentionally avoids some rewrites:
- method chaining like `a()?.b()?` is not supported
- `?` in `for` initialization statements is not supported yet
- expression statements like `f()?` require `f` to return only `error`; use `_ = f()?` when discarding non-error return values
- custom handlers use the generated `err` variable and must return or otherwise handle control flow themselves