Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: value of type 'String' has no member 'hasSuffix' in Swift switch

I'm following tutorials from Swift.org

The below example of switch statement throws an error.

let vegetable = "red pepper"
switch vegetable {
case "celery":
    print("Add some raisins and make ants on a log.")
case "cucumber", "watercress":
    print("That would make a good tea sandwich.")
case let x where x.hasSuffix("pepper"):
    print("Is it a spicy \(x)?")
default:
    print("Everything tastes good in soup.")
}

The error am getting is : error: value of type 'String' has no member 'hasSuffix' case let x where x.hasSuffix("pepper"): Am using ubuntu 14.04 and my version of Swift is swift --version Swift version 3.0 (swift-3.0-PREVIEW-2)

like image 408
Krishnadas PC Avatar asked Nov 06 '16 15:11

Krishnadas PC


1 Answers

The hasSuffix(_:) member of String is bridged from NSString (and in so from Foundation). When working with Swift in Xcode Playgrounds and projects, this method is available from the Swift standard library, whereas when compiling Swift from e.g. the IBM sandbox/your local Linux machine, the Swift std-lib version is not accessible, whereas the one from core-libs Foundation is.

To have access to the latter implementation, you need to explicitly import Foundation:

import Foundation // <---

let vegetable = "red pepper"
switch vegetable {
case "celery":
    print("Add some raisins and make ants on a log.")
case "cucumber", "watercress":
    print("That would make a good tea sandwich.")
case let x where x.hasSuffix("pepper"):
    print("Is it a spicy \(x)?")
default:
    print("Everything tastes good in soup.")
}

Most Swift tutorials will assume execution via Xcode, and import Foundation can be good first attempted remedy for any "... has no member ..." errors when compiling Swift outside of Xcode.


Details

As @Hamish points out in a comment below (thanks!), one implementation of hasSuffix(_:) is available from the standard library, with the requirement of _runtime(_ObjC), however.

From swift/stdlib/public/core/StringLegacy.swift:

#if _runtime(_ObjC)

// ...

public func hasSuffix(_ suffix: String) -> Bool { 
    // ...
}

#else
// FIXME: Implement hasPrefix and hasSuffix without objc
// rdar://problem/18878343
#endif

Another implementation can be used in case the one above is not accessible (e.g. from Linux). Accessing this method requires an implicit import Foundation statement, however.

From swift-corelibs-foundation/Foundation/NSString.swift:

#if !(os(OSX) || os(iOS))
extension String {

    // ...

    public func hasSuffix(_ suffix: String) -> Bool {
        // ... core foundation implementation
    }
}
#endif
like image 192
dfrib Avatar answered Nov 13 '22 23:11

dfrib