Swift method that takes either String or Substring as parameter

Viewed 1601

I've been trying to learn how the new Swift 4 Strings and Substrings work.

Since most of what you can do to a String you can also do to a Substring, I was trying to find a way to combine the following two methods into one:

static func isConsonant(ipa: String) -> Bool {
    return "ptkʧfθsʃbdgʤvðzʒmnŋlwjhrʔɾ".contains(ipa)
}

static func isConsonant(ipa: Substring) -> Bool {
    return "ptkʧfθsʃbdgʤvðzʒmnŋlwjhrʔɾ".contains(ipa)
}

I thought I recall reading something about StringProtocol being the link, but this doesn't work:

static func isConsonant(ipa: StringProtocol) -> Bool {
    return "ptkʧfθsʃbdgʤvðzʒmnŋlwjhrʔɾ".contains(ipa)
}

with the error being

Protocol 'StringProtocol' can only be used as a generic constraint because it has Self or associated type requirements

Is there a parameter type that would accept either String or Substring?

1 Answers

Make it generic

func isConsonant<T>(ipa: T) -> Bool where T: StringProtocol {
    return "ptkʧfθsʃbdgʤvðzʒmnŋlwjhrʔɾ".contains(ipa)
}

in the same way as other StringProtocol methods, such as

func contains<T>(_ other: T) -> Bool where T : StringProtocol
func appending<T>(_ aString: T) -> String where T : StringProtocol
// ...

You could also make it an extension method or property of StringProtocol

extension StringProtocol {
    var isConsonant: Bool {
        return "ptkʧfθsʃbdgʤvðzʒmnŋlwjhrʔɾ".contains(self)
    }
}

but that bears the danger of name conflicts with other frameworks.

Related