在Golang中实现嵌套矩阵的惯用方式

  1. I am trying to represent a hypergraph in memory. Are there any better data structures for this task beside nested matrices? A nested matrix is a matrix which can have elements of both the "native" type (let's say int for the sake of simplicity) and matrices.

  2. This is the beginning of such a matrix. Are there any rough edges in the code, to make it look more idiomatic? How to make it look more idiomatic?

The code:

package main

import "fmt"

type Matricial interface {
    Put(interface{}, ...int)
    Get(...int) interface{}
}

type Matrix struct {
    Matricial
    values map[int]interface{}
}

func NewMatrix() *Matrix {
    m := &Matrix{}
    m.values = make(map[int]interface{})
    return m
}

func (m *Matrix) Set(atom interface{}, pos ...int) {
    firstdim := pos[0]
    if val, ok := m.values[firstdim]; ok {
        fmt.Println("map key exists", val)
        switch converted := val.(type) {
        case int:
            m.values[firstdim] = converted
        default:
            fmt.Println("ERR: unknown type: %T", val)
        }
    } else {
        if len(pos[1:]) > 0 {
            newm := NewMatrix()
            m.values[firstdim] = newm
            newm.Set(atom, pos[1:]...)
        } else {
            m.values[firstdim] = atom
        }
    }
}
func (m *Matrix) Get(pos ...int) interface{} {
    if len(pos) == 1 {
        return m.values[pos[0]]
    } else {
        switch accessor := m.values[pos[0]].(type) {
        case Matricial:
            return accessor.Get(pos[1:]...)
        default:
            return nil
        }
    }
    return nil
}

func main() {
    m := NewMatrix()
    m.Set(42, 2, 3, 4)
    m.Set(43, 0)
    fmt.Println(m.Get(2, 3))
    fmt.Println(m.Get(2, 3, 4))
    fmt.Println(m.Get(0))
}

The data structure must allow connecting hyperedges with other hyperedges (i.e. handling hyperedges as though they were nodes).

  1. A nested matrix (adopting your definition of the term) seems a reasonable representation for hypergraph, not knowing anything more about your application anyway. An example Go implementation is the power set example at Rosetta code.

  2. It is not idiomatic to embed an interface. For example, if you rename the Put method of Matricial to be Set, which is what I think you meant, then you can just delete the Matricial field of Matrix and your program produces the same output.