Gold Challenge Protocol Conformance


#1

While working the Gold Challenge on page 236, I am having trouble with getting the BookCollection struct to conform to the itemForRow(row:column:) method of the TabularDataSource protocol. As instructed in the book, the protocol is defined as:

protocol TabularDataSource { var numberOfRows: Int { get } var numberOfColumns: Int { get } func labelForRow(row: Int) -> String func labelForColumn(column: Int) -> String func itemForRow(row: Int, column: Int) -> Int }
The problem is that the Book struct has two String types and one Int type for its properties, like so:

struct Book { let title: String let author: String let amazonRating: Int }
My attempt at getting conformance is thus:

func itemForRow(row: Int, column: Int) -> Int { let book = books[row] switch column { case 0: return book.title case 1: return book.author case 2: return book.amazonRating default: fatalError("Invalid row!") } }
Obviously the compiler complains about the attempt to return String types when it is expecting an Int. The exercise requires BookCollection to conform to TabularDataSource, so I must be missing something here. What is it?


#2

In protocol change the definition of itemForRow to

func itemForRow(row: Int, column: Int) -> String

in the struct BookCollection where itemForRow is defined make the same change and
make case 1 read

case 1: return “(item.review)”

so requested for data in either column will return a string.

In print table double check to see if the code for the first line properly determines the max width needed for each column when filling in “columnWidths”

As an error check modify the function padding to catch negative padding amounts and not give a fatal error

func padding(amount: Int) -> String {
var paddingString = ""
if amount < 0 {
print(“Negative padding; (amount)”)
return paddingString
}
for _ in 0 …< amount { paddingString += " " }
return paddingString
}


#3

Ah yes, it did not occur to me to just convert the Int to a Sting literal. I am shaking my head because your solution is so simple, and I cannot believe that I didn’t think of that before.

Many thanks! :smiley:


#4

Also there is the option to change the protocol func to…

The result of calling itemForRow in the printTable func is consequently converted into a string literal.


#5

[quote=“badbluberries”]Also there is the option to change the protocol func to…

The result of calling itemForRow in the printTable func is consequently converted into a string literal.[/quote]

Thanks for this. I didn’t realize that this is all I had to do to get this to work. I converted that line to return a string in my solution in the other thread. Thanks!!!


#6

[quote=“badbluberries”]Also there is the option to change the protocol func to…

The result of calling itemForRow in the printTable func is consequently converted into a string literal.[/quote]

My first thought was to change the protocol on that to “-> String”, but “-> Any” sounds like a better idea. But did I miss something in the book up to this point where it mentioned the possibility of using “-> Any”? And if not, how were we supposed to know about this option (I don’t recall seeing Swift offering it as a fix when it was complaining about the error)? It also seems a bit misleading to me to have the book issue a challenge to conform to a protocol in which the ONLY way seems to be to change the protocol to fit the challenge and also have to “fix” the previous items adhering to the protocol as well (or is there some solution where it could adhere somehow without changing the protocol)?