У меня возникают проблемы с добавлением объектов в scala.collection.mutable.ListBuffer. Я знаком с соответствующим API и знаю, что обычно вы используете метод + = или ++ = для добавления объекта или последовательности объектов.Проблемы с добавлением объектов в ListBuffer в Scala
Я реализую карточную игру с поддержкой сети и имею простую задачу, добавив некоторые выбранных карт в Список ручных карт. В следующем коде я собираюсь получить ссылку на Список ручных карт (ListBuffer), напечатать размер ListBuffer, добавить выбранные карты и распечатать размер снова.
// get the references and ensure that it are rally ListBuffers/Lists
val handCards: mutable.ListBuffer[ClientCard] = playerPanel.player.handCards
val chosenCards: List[ClientCard] = _chosenCards
// print the number of elements per list
println("number of hand cards: " + handCards.size)
println("number of chosen cards: " + chosenCards.size)
// append the chosen cards to the hand cards
println("append operation: " + handCards + " ++= " + chosenCards)
handCards ++= chosenCards
// print the number of hand cards again
println("number of hand cards: " + handCards.size)
В результате можно было бы ожидать, что размер handCards будет расти на размер выбранных карт. Но выход (формируется):
number of hand cards: 5
number of chosen cards: 2
append operation: ListBuffer(
[email protected],
[email protected],
[email protected],
[email protected],
[email protected]
) ++= List(
[email protected],
[email protected]
)
number of hand cards: 5
Таким образом, элементы не были добавлены.
Клиентская карта всегда является представителем «настоящей карты» и состоит только из информации, необходимой для рисования карты.
trait ClientCard extends AnyRef with ClientObject with CardLike
trait ClientObject extends Serializable {
def uid: Int
}
trait CardLike {
val imagePath: String
}
ClientCard создается в классе карты:
def clientCard = new ClientCard() {
val uid = Card.this.hashCode()
val imagePath = CardTemplate.cardFolder + Card.this.imageFilename
}
И есть ClientPlayer (представитель "реального игрока"), где ListBuffer создан:
// definition of ClientPlayer trait
trait ClientPlayer extends ClientObject {
val victoryPoints: Int
val handCards: mutable.ListBuffer[ClientCard]
val playedCards: mutable.ListBuffer[ClientCard]
}
// piece of code to create a client player
def clientPlayer = new ClientPlayer() {
val uid = Player.this.hashCode()
val victoryPoints = Player.this.victoryPoints
val handCards = new mutable.ListBuffer[ClientCard]
handCards ++= (Player.this.handCards.map(_.clientCard))
val playedCards = new mutable.ListBuffer[ClientCard]
playedCards ++= Player.this.playedCards.map(_.clientCard)
}
Кто-нибудь знает, что здесь происходит не так? Или быть более общим: какие существуют обстоятельства, чтобы предотвратить успешное добавление объектов в ListBuffer?
Редактировать: Есть что-то, что я забыл упомянуть и что, казалось, вызывало это странное поведение. После создания handCards ListBuffer он отправляется по сети и поэтому сериализуется и десериализуется снова.
После комментария Рекса Керра я попытался создать метод глубокой копии для ClientPlayer и скопировать каждый ClientPlayer сразу после его получения. Это решило проблему. У кого-нибудь есть объяснение этого поведения?
'ListBuffer' делает некоторые причудливые вещи за кулисами, если он преобразуется в список. У вас есть какие-либо 'toList' или тому подобное в коде? Я не могу воспроизвести поведение, которое вы наблюдаете. –
Неглубоко. Но после создания handCards ListBuffer он отправляется по сети и поэтому сериализуется и десериализуется снова. – Zwackelmann
Это действительно было вызвано сериализацией и десериализацией ListBuffer. Я создал метод глубокой копии для ClientPlayer и создал копию для каждого объекта ClientPlayer сразу после его получения. Это решило проблему. – Zwackelmann