12

I want to add a class function into extension:

extension String {
     class func test () {
     }
}

I get the error: Class methods are only allowed within classes; use 'static' to declare a static method

Or how should i call " String.test()"

But for NSString

extension NSString {
    class func aaa () {
    }
}

no errors.

If i add static keyword:

extension String {
    static func aaa () {
        self.stringByAppendingString("Hello")
    }
}

Got: Expression resolves to an unused function,

So how should i add a class function also want to use self. method.

EDIT: This works!

extension String {
    static func aaa (path:String) -> String {
        return path.stringByAppendingString("Hello")
    }
}

but about @lan's answer:

mutating func bbb(path: String) {
    self += "world"
}

When i type it appears like this:

String.bbb(&<#String#>)
String.bbb(&"nihao")

Cannot invoke 'bbb' with an argument list of type '(String)'

3 Answers 3

17

Class and static functions are not called on an instance of a class/struct, but on the class/struct itself, so you can't just append a string to a class.

Apple Documentation:

Within the body of a type method, the implicit self property refers to the type itself, rather than an instance of that type.

You can, however, append a string to a variable instance of a String using the mutating keyword:

extension String {
    mutating func aaa() {
        self += "hello"
    }
}

let foo = "a"
foo.aaa() // ERROR: Immutable value of type 'String' only has mutating members named 'aaa'

var bar = "b"
bar.aaa() // "bhello"

If you are trying to use a pointer to a string as a parameter, you can use the inout keyword to alter the inputed string:

extension String {
    static func aaa(inout path: String) {
        path += "Hello"
    }
}

var foo = "someText"
String.aaa(&foo)
foo //someTextHello
Sign up to request clarification or add additional context in comments.

8 Comments

how should i call "String.add()" ?
On an instance of a String, not on the class itself. It makes absolutely no sense calling add on the type String because there is no value to append to
hey @lan, can you check my edied question again?
@WilliamHu I think there's a fundamental misunderstanding here. What you need is an instance method, not a type method. This will require you to create an instance of the type that you're working on to call the method, not directly on the type itself, i.e. let x = "str" x.someMethod(), not String.someMethod().
@Ian Ah yeah the comment makes it much more clear. Anyways this was really useful, so thanks!
|
4

While correct, it's somewhat atypical to see a mutating member added to a String extension as shown in Ian's answer. Strings (and value types in general) are meant to be immutable so the only way to use a mutating method is to declare instances var at the call site. Most of the time in your code you should be using let constants.

As such, it is much more common to extend structs to return new instances. So this is typical:

extension String {
    func appending(_ string: String) -> String {
        return self + string
    }
}

and then at the call site:

let hello = "Hello, "
let helloWorld = hello.appending("World!")

You'll note of course that I'm not using static at all. That's because appending(_:) needs to use the current instance value of the String we're appending to, and class/static do not refer to instances and therefore do not have values.

Comments

0

"Within the body of a type method, the implicit self property refers to the type itself, rather than an instance of that type."

Thus when you extend a type by adding a type method you can only call other type methods through self. If you want to call an instance method you need to create an instance and call a method on that.

1 Comment

Thank you, you give me the hint too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.