Котлин Варарг А Варарг Б - PullRequest
0 голосов
/ 06 января 2019

Я пытаюсь реализовать класс Filter, который может состоять из других классов Filter. Цель состоит в том, чтобы каждый фильтр мог обрабатывать объект и возвращать логическое значение, и, если он состоит из нескольких фильтров, он вычисляет AND всех своих фильтры.

Я пытаюсь заставить одного из конструкторов получить предикаты vararg , которые необходимо преобразовать в vararg фильтров. Компилятор говорит, что ни одна из функций (первичных и первых вторичных конструкторов) не может быть вызвана с этими параметрами.

Насколько я понимаю, * следует преобразовать List<Filter<T>> в vararg Filter<T>, но это не работает.

class Filter<in T>(private vararg val filters: Filter<T>) {
    constructor(predicate: (T) -> Boolean) : this(Filter(predicate))
    constructor(vararg predicates: (T) -> Boolean) : this(Filter<T>(*(predicates.map { predicate -> Filter<T>(predicate) })))

    fun process(input: T): Boolean {
        for (filter in filters) { if (!filter.process(input)) return false }
        return true
    }
}

Что я могу сделать, чтобы достичь этого?

Кроме того, это большие издержки итерации по фильтрам только одного предиката по сравнению с простой проверкой предиката (учитывая, что это будет вызываться много раз для фильтрации списка)?

1 Ответ

0 голосов
/ 06 января 2019

Нет '*' - оператор распространения и может использоваться в массиве для передачи в качестве параметра vararg. Вам нужно будет изменить свой последний конструктор на:

constructor(vararg predicates: (T) -> Boolean) : this(*predicates.map { Filter(it) }.toTypedArray())

Предикаты - это сопоставление со списком Filter, а затем список преобразуется в массив и передается как vararg с помощью оператора распространения.

Обратите внимание, что вам не нужно указывать какой-либо тип, потому что компилятор может выводить эти типы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...