I'm an experience programmer, but I just started learning Swift (version 4) recently.
I found it difficult to do simple tasks, even like "give me the 4th Character
of this String
".
I tried to write these two simple functions:
// isHexCharacter returns whether a Character is hexadecimal or not
func isHexCharacter(_ c: Character) -> Bool {
switch c {
case "0", "1", "2", "3", "4", "5", "6", "7",
"8", "9", "A", "B", "C", "D", "E", "F":
return true
default:
return false
}
}
// isHexString returns whether a String (or Substring) consists
// entirely of hexadecimal characters
func isHexString(_ s: StringProtocol) -> Bool {
for c in s {
if !isHexCharacter(c) {
return false
}
}
return true
}
But the compiler bit me:
demo.swift:20:23: error: protocol 'StringProtocol' can only be used
as a generic constraint because it has Self or associated
type requirements
func isHexString(_ s: StringProtocol) -> Bool {
^
demo.swift:21:14: error: using 'StringProtocol' as a concrete type
conforming to protocol 'Sequence' is not supported
for c in s {
^
My questions are:
I don't understand the compiler messages. What do they mean? Why couldn't I use
StringProtocol
as a parameter? Did I miss something?I know that there may be standard library functions that exactly fit my job above, but it's just a demo. My point is knowing how to write more complicated functions that work on either
String
orSubstring
. How could I do that?
Thank you so much!
UPDATED: 2017-09-28 08:05 UTC
As suggested by @martin-r, now I changed isHexString
like this:
func isHexString<S: StringProtocol>(_ s: S) -> Bool {
for c in s {
if !isHexCharacter(c) {
return false
}
}
return true
}
It works perfectly!
However, I tried to create the following code:
protocol Animal {
func eat()
}
class Cat : Animal {
func eat() {
print("Meow")
}
}
func animalEat(_ a: Animal) {
a.eat()
}
var kitty = Cat()
animalEat(kitty)
I have no idea why this works without error. Why does the function animalEat
work fine without generics?