#scala
#scala
Вопрос:
Отказ от ответственности: я довольно новичок в любом современном виде кодирования. (БАЗОВЫЙ Паскаль еще в средней школе, немного Python несколько лет назад, и теперь я пытаюсь научить себя Scala.)
Предполагается, что этот код генерирует рандомизированную колоду карт с мастями и значениями, которые я настраиваю в первых двух строках. У меня есть код, который работает, используя изменяемые переменные, но я всегда читаю, что лучше избегать изменяемых переменных, поэтому я попытался использовать вместо этого «yield». Это был результат после того, как я изменил код:
import util.Random.shuffle
val suits = Vector[String]("s", "m", "p")
val values = Vector[Int](1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 5, 5, 9)
class Card(val suit:String, val value:Int) {}
class Deck() {
var cardsInDeck:Vector[Card] = Vector()
}
def makeDeck(suits:Vector[String], values:Vector[Int]):Vector[Card] = {
for (i <- suits) yield {
for (j <- values) new Card(i, j)
}
}
val TheDeck = new Deck
TheDeck.cardsInDeck = util.Random.shuffle(makeDeck(suits, values))
for (i <- TheDeck.cardsInDeck) {
println(s"${i.suit}${i.value}")
}
Это выдает мне сообщение об ошибке, указывающее на стрелку после «i» и говорящее о несоответствии типов.
Есть ли что-нибудь подобное, что будет работать?
Если нет, как вы думаете, я должен просто придерживаться исходной версии изменяемой переменной? (Я предполагаю, что вы можете себе представить, как это было в основном — начните с переменной со значением по умолчанию и добавляйте к ней по одному элементу за раз, выполняя итерации по вложенным циклам.)
Наконец, я предполагаю, что в Scala уже есть какой-то встроенный метод или другой, который позволяет мне делать это бесплатно. Я думаю, что полезно выяснить, как это сделать вручную для общих педагогических целей, но если есть однострочный метод, который я действительно должен использовать, мне интересно узнать об этом.
Заранее благодарю вас…
Ответ №1:
def makeDeck(suits: Vector[String], values: Vector[Int]): Vector[Card] = {
for {
i <- suits
j <- values
} yield new Card(i, j)
}
Вы забыли второй yield перед new Card
. Однако нет необходимости вкладывать циклы for, вместо этого структурируйте их, как указано выше.
Вам следует подумать cardsInDeck
о создании параметра a val
и конструктора, поэтому Deck
он может быть неизменяемым, как Card
есть. Это также было бы удобно для Deck
и Card
для классов case.
Комментарии:
1. Спасибо. Я еще не совсем понял, в чем преимущество классов case, но я все еще учусь. Что касается того, должна ли колода быть изменяемой или нет, сейчас кажется, что так и должно быть, поскольку она будет расти и уменьшаться по мере продолжения игры. Разве это не следует, хотя?
2. Кстати, мне даже не приходило в голову, что там нужен второй yield, но в любом случае мне нравится ваш способ лучше, легче читать и т.д.
3. Deck может быть изменяемым или неизменяемым. Если вы сделаете его неизменяемым, для каждой операции, которая изменяет колоду, потребуется создать новый объект Deck. Иногда это неудобно для игр и других симуляций.