Даункинг Полиморфизм и отведения - PullRequest
0 голосов
/ 20 апреля 2020

Я создал игрушечную проблему, чтобы понять, почему я не могу установить значение свойства после понижения рейтинга. Проблема в представлении контроллера # 3: я хочу присвоить значение свойству artist.

import Foundation

protocol MediaType {
    var year: String? { get set }
}

struct Song: MediaType {
    var artist: String?
    var musicians: [String]?

    // Implement Protocol `MediaType`
    var year: String?
}

class MediaStateController {
  var media: MediaType?
}

//
// view controller 1: controller does not know the media type just yet.
//
let stateController = MediaStateController() // media remains nil for now
print(stateController.media is Song) // false

//
// view controller 2: knows the media type so it can assign the media type.
//
stateController.media = Song()

print(stateController.media is Song) // true
print(stateController.media as? Song) // Optional(Song(artist: nil, musicians: nil, year: nil))
print(stateController.media) // Optional(Song(artist: nil, musicians: nil, year: nil))
print(type(of: stateController.media)) // Optional<MediaType>

// view controller 3: knows only the artist name but not the musicians. 
if var song = stateController.media as? Song {
    song.artist = "SomeArtist" // ISSUE: this does not set the value (see print-out below)
}

print(stateController.media as? Song) // Optional(Song(artist: nil, musicians: nil, year: nil))


if var song = stateController.media as? Song {
    // makes no sense to not use song, but let's do it anyway.
    // (stateController.media as? Song)?.artist = "SomeArtist" // error: cannot assign to immutable expression of type 'String?'
}
print(stateController.media as? Song) // Optional(=Song(artist: nil, musicians: nil, year: nil))

if var song = stateController.media as? Song {
      // THIS DOES SET THE VALUE, but why?
      song.artist = "SomeArtist" 
      stateController.media = song
    }
print(stateControllaer.media as? Song) // Optional(Song(artist: Optional("SomeArtist"), musicians: nil, year: nil))

1 Ответ

0 голосов
/ 20 апреля 2020

Song - это структура, которая является типом значения в Swift. В этом примере:

// view controller 3: knows only the artist name but not the musicians. 
if var song = stateController.media as? Song {
    song.artist = "SomeArtist" // ISSUE: this does not set the value (see print-out below)
}

Вы копируете исходный экземпляр Song в новую переменную, а затем обновляете свойство artist этой копии. Эта копия затем выбрасывается, как только вы выходите из области действия вашего if var.

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