9 ms·
"Swift 4 includes a faster, easier to use String implementation that retains Unicode correctness and adds support for creating, using and managing substrings."
by swivelmaster 9y ago
"Swift 4 includes a faster, easier to use String implementation that retains Unicode correctness and adds support for creating, using and managing substrings."
This alone is grounds for opening and drinking very expensive champagne and/or wine.
- jhancock 9y agoAs a new swift'er working on an app with my 12 year old son, I reasonate with your comment. We were near the end of our first app and hit a need in swift 3 to figure out locale/language settings so needed to manipulate strings. I was shocked at how unobvious it seemed. Fortunately, I found a swift playground cheat sheet and left it to my son to explore. A couple hours later he had it worked out ;)
- abalone 9y agovar wine = Set<String>() wine.insert("Champagne")
- willtim 9y agoSo strings are mutable? I'm not sure that's a reason to celebrate.
- slavapestov 9y agoThe example does not demonstrate mutability of strings; it is constructing a set of strings and inserting a string element. Only the set is being mutated. But yes, in Swift, arrays, dictionaries, sets and strings are all mutable. They are also value types, so mutation is a purely local effect.
- xrisk 9y agoWould that not make passing around data expensive? Or are you expected to pass some kind of pointer instead?
- slavapestov 9y agoCopy-on-write alleviates some of the overhead. Copies are only performed where required to preserve value semantics.
- mantas 9y agoAll of these can be both mutable or immutable. And converted as needed let array = [1, 2, 3] var mutableArray = [4, 5, 6] var anotherMutable = array Not sure how much optimisation is done under the hood, but Swift compiler loves to complain about mutable structures that are not ever edited.
- masklinn 9y agoThese are all copy-on-write boxed types with value semantics: the value you pass around is a pointer (with some additional data) and Swift has mechanisms/API which let the implementor copy the backing buffer on mutation if necessary: https://developer.apple.com/documentation/swift/2429905-isknownuniquelyreferenced https://developer.apple.com/documentation/swift/2429905-iskn...
- fauigerzigerk 9y agoI think what the example is supposed to demonstrate is that champagne is a type of wine.
- mikeash 9y agoStrings (and arrays and sets and dictionaries) are neither mutable nor immutable in Swift, they're just values. Mutability is a property of where they're stored, not the types themselves. They work just like numbers do in most programming languages: you wouldn't say that Java's `int` is mutable or immutable, it just is. It may be stored in a mutable or immutable location, but the type itself doesn't have that property.
- dep_b 9y agoOof, magic strings. Always use enums! enum Booze: String { case wine, case champagne, case beer, case whiskey } let wine = [Booze.champagne] </ocd>
- golergka 9y agoI feel like adding a pull request to add whisky to the list. Some of us prefer scotch.
- ryan-koch 9y agoDefinitely have to +1 this. I'd be happy to write some tests to get scotch on board.
- koolba 9y agoI'm not sure if it was intentional but "case beer" made me smile.
- meggar 9y agowine's type should conform to a Stack protocol so you can pop champagne.
- rimliu 9y agoWhy are these String, not just enums?
- dep_b 9y agoBecause it's replacing a Magic String?
- timjver 9y agoYou don't need commas :)
- abalone 9y agoNooooooo... you're right about enums but this codifies the same error I was trying to elucidate with code. Here, let's try this: enum Booze { case Wine(region: String) case Beer case Whiskey } let drink = Booze.Wine(region: "Champagne") Now.. Anyone want to demonstrate how to use enums for the wine region or, say, whiskey subtypes? Should we use classes?
- developer2 9y ago>> support for creating, using and managing substrings Can I finally extract a substring from the middle of a string using integer offsets, in one line? Something like string.utf8.substr(3, 5)? Or does it still take an absolutely insane and unacceptable 4 lines of code with throwaway temp variables to track the start and end indexes? The inability to do basic string manipulations is a major turnoff, to the point it makes the entire language look like a bad joke.
- fauigerzigerk 9y agoYou could do something like String(s.dropFirst(3).prefix(5))
- slavapestov 9y agoA String in Swift is a sequence of graphemes, unlike most languages which model strings as sequences of code points or just rawutf8, so there's no way to do efficient O(1) indexing. This is why the API is a bit more complex than you'd like.
- developer2 9y agoI keep getting this inaccurate answer of "they're just grapheme code points - you can't do it". That is why my example specifically used the .utf8 view. It's already possible to do exactly what I'm talking about, but it takes 4 complex lines of code, needing two calls to index() with startIndex/endIndex references and offsetBy arguments. The existing solution to this problem already uses integers (the offsetBy arguments)! I'm not talking about refactoring the String type, or breaking backwards compatibility. There would be no change in how the underlying String storage or access works. It's about adding a level of (zero overhead!) abstraction to simplify a common, basic operation. Every other language I've ever touched has easy to use substrings. It makes absolutely no sense that Swift requires assigning throwaway constants to represent the start and end indexes for a simple substring extraction. There's this level of superiority regarding the purity and correctness of Swift's String type that clouds developers' ability to see that there is no limitation to doing this. It blows my mind that the most modern major language is this clunky.