Golang中的pubsub替代

I have simple task that already done in javascript using pubsub, here is the task:

I have object let say A and another 2 object that have interest in some element(string in this case), let say Foo interest in element m, n and Bar interest in element n, o, p. The interest can intersect.

The A object have method adding/remove element and when that object contain m, n element which Foo interest in, then that object stored in Foo here's the pseudo code in javascript using pubsub

var A = {};

var Foo = {
    interests: ['m', 'n'],
    storedObj: {},
    tempObj: {}
};

// Bar same as Foo with different interest ['n', 'o', 'p']

// somewhere in Foo and Bar constructor
// Foo and Bar subscribe too each interests element
// for each interests when add
subscribe('add'+interest, function(obj) {
    // store this obj in tempObj and increment until satisfy all 
    // interest
    tempObj[obj]++;

    // if this obj satisfy all interest then store it in array of obj
    if(tempObj[obj] === len(interests)) {
        storedObj[obj] = true;
    }
});

// for each interests when remove
subscribe('remove'+interest, function(obj) {
    // remove from storedObj
    delete storedObj[obj];

    // decrement tempObj so it can be used for later if the interest 
    // is adding again
    tempObj[obj]--;
});

// inside A prototype
prototype.add = function(interest) {
    publish('add'+interest, this);
    return this;
}
prototype.remove = function(interest) {
    publish('remove'+interest, this);
    return this;
}

// implementation
A.add('m')
 .add('n')
 .add('o')

// then A is stored inside Foo but not in Bar because A doesn't have 
// `p`, but it still stored Bar.tempObj and have value 2 and waiting 
// for `p` to be add

A.remove('m')
 .add('p')

// then A is removed from Foo and stored in Bar

I want to porting this task into golang but i don't want using pubsub, i want more idiomatic to golang way. NOTE: i already done using pubsub in golang as well.

Can you show me how to do it in golang? i'm thingking using channel, but and can't find the solution.

Just to give you an idea, not necessarily your real use case.

package main

import (
    "fmt"
    "time"
)

type Publisher struct {
    subscription map[string]chan string
}

func (p *Publisher)Subscribe(interest string) chan string{
    if p.subscription == nil {
        p.subscription = make(map[string]chan string)
    }
    p.subscription[interest] = make(chan string)
    return p.subscription[interest]
}

func (p *Publisher) Add(val string) {
    if p.subscription[val] != nil {
        fmt.Println("Adding " + val)
        p.subscription[val] <- "added " + val
    }
}
func (p *Publisher) Remove(val string) {
    if p.subscription[val] != nil {
        p.subscription[val] <- "removed " + val
    }
}

type Subscriber struct {
    subscriptions [] chan string
    publisher *Publisher
}

func (s *Subscriber) RegisterInterest(interest string){
    s.subscriptions = append(s.subscriptions, s.publisher.Subscribe(interest))
}
func (s *Subscriber) run(channel chan string) {
    for  {
        fmt.Println("Waiting for message")
        m := <- channel
        fmt.Println("Got message : " + m)
    }
}
func (s *Subscriber) Listen()  {
    for _, elem := range s.subscriptions {
        go s.run(elem)
    }

}
func main() {
    pub := Publisher{}
    sub := &Subscriber{publisher: &pub}
    sub.RegisterInterest("m")
    sub.RegisterInterest("n")
    sub.Listen()
    pub.Add("m")
    pub.Add("n")
    pub.Remove("m")
    pub.Remove("n")
    time.Sleep(time.Second * 10)
}