Skip to content

alexpantyukhin/go-pattern-match

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

71 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go pattern matching

Mentioned in Awesome Go Go Report Card Build Status codecov GoDoc LICENSE

It's just another approach for using pattern matching in Go. I have been inspired by python pattern matching that's why I wanted to make an attempt to rewrite something similar in Go :) For now the following matching are implemented :

  • Simple types (like int, int64, float, float64, bool..).
  • Struct type.
  • Slices (with HEAD, TAIL, OneOf patterns).
  • Dictionary (with ANY, OneOf pattern).
  • Regexp.
  • Adding custom matching (ability to add special matching for some structs for example)

Usages

Fibonacci example:

func fib(n int) int {
	_, res := match.Match(n).
		When(1, 1).
		When(2, 1).
		When(match.ANY, func() int { return fib(n-1) + fib(n-2) }).
		Result()

	return res.(int)
}

Simple types:

isMatched, mr := match.Match(42).
                When(42, 10).
                Result()
// isMatched - true, mr - 10

With Structs:

  • Simple check value by type
val := TestStruct{1}

isMatched, _ := Match(val).
    When(func(TestStruct) {},  1).
    Result()
  • Check value by type and condition
val := TestStruct{1}

isMatched, _ := Match(val).
	When(func(ts TestStruct) bool { return ts.value == 42 }, 1).
	When(func(ts AnotherStruct) bool { return ts.stringValue == "hello" }, 2).
	Result()

With Maps:

isMatched, mr := match.Match(map[string]int{
                	"rsc": 3711,
                	"r":   2138,
                	"gri": 1908,
                	"adg": 912,
                }).
        	    When(map[string]interface{}{
                	"rsc": 3711,
                	"r":   2138,
                	"gri": 1908,
                	"adg": match.ANY,
            	}, true).
            	Result()

With Slices:

isMatched, mr := match.Match([]int{1, 2, 3, 4, 5, 6}).
            	When([]interface{}{match.HEAD, 3, match.OneOf(3, 4), 5, 6}, 125).
            	Result()

With regexps:

isMatched, mr := match.Match("gophergopher").
            	When("gophergopher", func() interface{} { return true }).
            	Result()

Without result:

func main() {
	Match(val).
	When(42, func() { fmt.Println("You found the answer to life, universe and everything!") }).
	When(ANY, func() { fmt.Println("No.. It's not an answer.") }).
	Result()
}

Installation

Just go get this repository with the following way:

go get github.com/alexpantyukhin/go-pattern-match

Full example

package main

import (
    "fmt"
    "github.com/alexpantyukhin/go-pattern-match"
)

func main() {
    isMatched, mr := match.Match([]int{1, 2, 3}).
        When(42, false).
        When([]interface{}{match.HEAD, 2, 3}, true).
        Result()


    if isMatched {
        fmt.Println(mr)
    }
}

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages