Переменная долота Объявление Синтаксис Значение rvs: Bool * - PullRequest
2 голосов
/ 22 февраля 2020

Глядя на объект DecoupledHelper и код класса DecoupledHelper, я вижу следующее.

object DecoupledHelper {
 def apply(rvs: Bool*) = new DecoupledHelper(rvs)
}

class DecoupledHelper(val rvs: Seq[Bool]) {
 def fire(exclude: Bool, includes: Bool*) = {

   (rvs.filter(_ ne exclude) ++ includes).reduce(_ && _)
 }
}

Я не понимаю синтаксис объявления параметров в методе apply. (rvs: Bool*). Что означает * в конце типа Bool . Глядя на параметры конструктора класса DecoupledHelper, он ожидает (rvs: Seq[Bool])

Означает ли это, что тип Bool* автоматически преобразуется в тип Seq[Bool]?

Хотя на этом может кто угодно также объясните, что делает метод rvs.filter?

1 Ответ

0 голосов
/ 26 февраля 2020

Как сказал Камьяр, Type* - это синтаксис Scala для переменного числа аргументов (также известный как "varags"). Это позволяет вам вызывать метод DecoupledHelper apply следующим образом:

val helper = DecoupledHelper(a, b, c) // calling apply on the companion object
// instead of
val helper2 = new DecoupledHelper(Seq(a, b, c)) // calling constructor of the class

Для новичков в долоте и Scala обратите внимание, что apply - это специальная функция Scala, который вызывается, когда вы "применяете" круглые скобки к объекту или экземпляру. Таким образом, DecoupledHelper(a, b, c) эквивалентно DecoupledHelper.apply(a, b, c).

. При этом кто-нибудь может также объяснить, что делает метод rvs.filter?

Он использует преимущества реализация долота, которую я бы не рекомендовал делать. ne - это функция Scala для нереферентно равных. Он позволяет вам проверить, не являются ли два объекта разными объектами в памяти.

В этом случае он позволяет вам делать такие вещи, как:

val helper = DecoupledHelper(a, b, c)
helper.fire()   // a && b && c
helper.fire(b)  // a && c

Теперь, потому что это опасно с использованием ссылочного равенство вместо фактического аппаратного равенства (и есть причины реализации, которые мотивировали это), то, что должно работать, не работает:

val helper = DecoupledHelper(a, b, c)
val d = b           // Same reference
val e = WireInit(b) // Equivalent Wire but different reference
helper.fire(d)  // a && c
helper.fire(e)  // a && b && c

d указывает на тот же объект на куча как b, но e не соответствует, несмотря на то, что она эквивалентна с аппаратной точки зрения.

Для получения дополнительной информации см. соответствующий отчет об ошибке и обсуждение: https://github.com/chipsalliance/rocket-chip/issues/1616

...