bilue / swift-style-guide Goto Github PK
View Code? Open in Web Editor NEWThis project forked from github/swift-style-guide
Style guide & coding conventions for Swift projects
License: Creative Commons Zero v1.0 Universal
This project forked from github/swift-style-guide
Style guide & coding conventions for Swift projects
License: Creative Commons Zero v1.0 Universal
In regards to only referencing self when explicitly required to do so:
I agree with a couple of the community points and would like to reconsider that we actually require the use of self in instance and class methods to make scope explicitly clear.
I've been thrashing through this idiom recently so it's not explicitly a 'pure swift' thing but more of a good way to encapsulate logic within a particular component.
Say you have a text field and you want to perform a stack of modifications to it, you have two ways to do this
func myCoolFunc() {
let textField = TextField(rect: CGRectZero)
label.attributedPlaceholder = ...
textField.attributedText =
textField.delegate = self (or some other class)
}
The problem being that what if myCoolFunc is called more than once, this is why you can use lazily evaluated closures on properties to guarantee they'll only be initialized once (and also they give you a convenient way to store item centric logic
lazy var myTextField : UITextField = {
let textField = TextField(rect: CGRectZero)
label.attributedPlaceholder = ...
textField.attributedText =
textField.delegate = self (or some other class)
return textField
}()
IIRC lazy attributes/properties are de facto thread-safe and lazy closures are only executed ONCE meaning you get a decoupling of your property elements from your actual imperative code (if you're exclusively laying out in code). Something I've been mulling over but something I think is a good addition to the guide. Happy to discuss with others.
This comes out of some discussion that maybe "Prefer let-bindings over var-bindings wherever possible" doesn't make sense as a guideline when the compiler already generates warnings for that as of Swift 2. After talking it over with @sboddeus we decided that it's still probably valuable as a guideline if it's rephrased as something along the lines of "prefer immutability over mutability wherever possible".
This is another kind of idiomatic Swift trick that again allows you to decouple certain implementations from your existing structures or classes. The best example is you might have a common view controller that you decide to add a map view to, but you only want to add annotations. Rather than having your class conform to the protocol, have an extension on your class conform
So rather than
class MyCoolViewController : UIViewController, MKMapViewDelegate
{
//my cool class goes here
}
We do the following definition
//regular class
class MyCoolViewController : UIViewController
{
//my wicked sick class goes here
}
extension MyCoolViewController : MKMapViewDelegate
{
//delegate conformance goes here
}
What you end up getting from this is a) separation of concerns, but b) locality of concerns, it's also a great way to extend and adapt a particular class if you're getting to code smell lengths of fat view controllers and need to add functionality (or want to expand existing Obj-C view controllers but want to use swell as heck Swift for building upon your existing apps)
I often find myself chaining functions like map
, filter
, and reduce
like so:
let totalSize = fileInfos
.map { fileInfo in
if (isSymlink(fileInfo) {
return resolveSymlink(fileInfo)
}
return fileInfo
}
.flatMap { $0[NSFileSize] as? CUnsignedLongLong }
.reduce(0, combine: +)
This is something I picked up from working on D3.js projects, and I find it aids readability when dealing with this style of function chaining.
In discussing this style of chaining methods in the Slack chat, @sboddeus brought up a good point that this seems to go against our recommendations for if
/else
statements. In that case, we advise that the else
goes on the same line as the if
statements closing brace like so:
if {
// ...
} else {
// ...
}
Following this precedent, our chaining would look like this:
let totalSize = fileInfos.map { fileInfo in
if (isSymlink(fileInfo) {
return resolveSymlink(fileInfo)
}
return fileInfo
}.flatMap {
$0[NSFileSize] as? CUnsignedLongLong
}.reduce(0, combine: +)
which doesn't look nearly as readable to me, but is worth considering for sakes of consistency.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.