Created
January 28, 2019 12:06
-
-
Save nicklockwood/9b4aac87e7f88c80e932ba3c843252df to your computer and use it in GitHub Desktop.
Withable.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Withable is a simple protocol to make constructing | |
/// and modifying objects with multiple properties | |
/// more pleasant (functional, chainable, point-free) | |
public protocol Withable { | |
init() | |
} | |
public extension Withable { | |
/// Construct a new instance, setting an arbitrary subset of properties | |
init(with config: (inout Self) -> Void) { | |
self.init() | |
config(&self) | |
} | |
/// Create a copy, overriding an arbitrary subset of properties | |
func with(_ config: (inout Self) -> Void) -> Self { | |
var copy = self | |
config(©) | |
return copy | |
} | |
} | |
//--------------------------------------------------- | |
// Example struct | |
struct Foo: Withable { | |
var bar: Int = 0 | |
var baz: Bool = false | |
} | |
// Construct a foo, setting an arbitrary subset of properties | |
let foo = Foo { $0.bar = 5 } | |
// Make a copy of foo, overriding an arbitrary subset of properties | |
let foo2 = foo.with { $0.bar = 7; $0.baz = true } | |
// Test | |
print("\(foo.bar), \(foo2.bar)") // 5, 7 |
it seems like builder pattern?
@dcutting as-yet unannounced. I did try using it in SwiftFormat but it didn't play nice with Xcode 9.2 for some reason (I don't want to drop support for Sierra just yet).
@wsof401 not really. The builder pattern usually applies to class-based languages like Objective-C or Java, where you use a mutable object as a factory for an immutable one. All of that is redundant in Swift where you have compound value types.
What this allows is so-called "point-free" coding style, where you can set or change properties of structs without creating intermediate variables.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice Nick, but now you've got me wondering what interesting project you're using this in... :)