2014-08-13 4 views
3

Я новичок в движении.Каков правильный способ записи отдельного канала в Go?

Я пытаюсь найти простой способ реализовать канал, который выводит только отдельные значения.

То, что я хочу сделать это:

package example 

import (
    "fmt" 
    "testing" 
) 

func TestShouldReturnDistinctValues(t *testing.T) { 

    var c := make([]chan int) 

    c <- 1 
    c <- 1 
    c <- 2 
    c <- 2 
    c <- 3 

    for e := range c { 
     // only print 1, 2 and 3. 
     fmt.println(e)  
    } 
} 

Должен ли я быть беспокойство по поводу утечки памяти здесь, если бы я использовать карту, чтобы помнить предыдущие значения?

Спасибо.

+0

Ваш дизайн выглядит так, будто вы пытаетесь сделать то, что вы не должны делать с каналами. Если заданный вами вопрос не является вашей фактической проблемой, а скорее проблемой, с которой вы столкнулись при попытке решить настоящую проблему, мы могли бы оказать вам лучшую помощь, когда вы покажете нам свою фактическую проблему. – fuz

+0

Если не так важно, чтобы тест дублирования был на 100% точным, вы можете рассмотреть возможность использования фильтра цветения (https://en.wikipedia.org/wiki/Bloom_filter). – fuz

+0

@FUZxxl Я пытаюсь постоянно ломать сайт для данных в течение определенного периода времени, прежде чем я закрою канал. Однако у меня проблема с получением дублированных данных, я пытаюсь найти простой способ получить только отдельные значения для потребителя канала. Благодарю. – Misterhex

ответ

5

Вы действительно не можете этого сделать, вам нужно как-то отслеживать значения, map[int]struct{}, вероятно, является наиболее эффективным для памяти способом.

Простой example:

func UniqueGen(min, max int) <-chan int { 
    m := make(map[int]struct{}, max-min) 
    ch := make(chan int) 
    go func() { 
     for i := 0; i < 1000; i++ { 
      v := min + rand.Intn(max) 
      if _, ok := m[v]; !ok { 
       ch <- v 
       m[v] = struct{}{} 
      } 
     } 
     close(ch) 
    }() 

    return ch 
} 
1

Я делал подобные вещи раньше, за исключением того, моя проблема была выходные входы в порядке возрастания. Вы можете сделать это, добавив обычную процедуру. Вот example:

package main 

func main() { 
    input, output := distinct() 

    go func() { 
     input <- 1 
     input <- 1 
     input <- 2 
     input <- 2 
     input <- 3 
     close(input) 
    }() 

    for i := range output { 
     println(i) 
    } 
} 

func distinct() (input chan int, output chan int) { 
    input = make(chan int) 
    output = make(chan int) 

    go func() { 
     set := make(map[int]struct{}) 
     for i := range input { 
      if _, ok := set[i]; !ok { 
       set[i] = struct{}{} 
       output <- i 
      } 
     } 
     close(output) 
    }() 
    return 
} 
Смежные вопросы