How can you initialize a struct with a closure parameter like this?
This works just like any function whose last parameter is a function. Trailing closure syntax is trailing closure syntax. The fact that the function is an initializer changes nothing.
So let me build up to it in stages. You know you can say:
func myfunc(whatever: () -> ()) {}
myfunc {}
Okay, but now let's make it a static method:
struct S {
static func myfunc(whatever: () -> ()) {}
}
S.myfunc {}
OK, but init
is a static method — it's just a static method whose name you are allowed to omit:
struct S {
let whatever: () -> ()
}
S {} // meaning S.init {}
How to create a struct parameter that is a closure with input, returning `some View` instead of `AnyView` in SwiftUI?
You just need to make ReusableView
generic and declare the return type of your closure as the generic type.
struct ReusableView<Output: View>: View {
let outputView: (String) -> Output
var body: some View {
outputView("Hello World")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ReusableView() {
CustomViewA($0)
}
}
}
Initialize struct with fields using closure
'structs without named fields' aren't exactly structs but tuple structs. Whereas the name of a tuple struct can be used the same way as a function name, it isn't true for a struct name. Using the struct name to instantiate one struct, you have to specify the name of the parameters:
println!("{:?}", wrap(1, |i|(D { x: i }))); // doesn't sound good, but works
Uncertain of this Swift struct syntax with closure
The declaration for the Effect type
struct Effect<T> {
Defines Effect as using a Generic type T. So you can create Effect objects that work on different types.
The line
let anIntInTwoSeconds = Effect<Int> { callback in
Creates an Effect object that operates on Ints, and assigns it to the variable anIntInTwoSeconds
.
The { callback in
part defines the closure for the Effect object. That declaration could be rewritten like this:
let anIntInTwoSeconds = Effect<Int>(run: { callback in
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
callback(42)
}
}
)
You can interpret as:
'Create an instance of the Effect struct, with a run
property that contains the closure that begins with "{ callback in"...'
(It's confusing because the run property is, itself, a closure. So we create an instance of Effect, and pass it a "run" value that's a closure.)
The "callback in" part, specifically, tells the compiler that, inside that closure, the parameter to the closure should be named "callback".
How to initialise closure variable in swift?
You can initialize closure
variable as,
init(onselecteditem : @escaping (Int) -> Void) {
self.onSelectedItem = onselecteditem
}
Assigning closure to struct variable in initialiser
There are two problems:
- Arguments are passed as
selected: ...
, notselected = ...
. - There is only a default memberwise initializer which takes all
properties as arguments.
So this would compile:
var settingsItem = SettingsItem(title: "Title",
textColor: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1),
selected: { return true },
action: {})
If you define a custom initializer with default argument values
struct SettingsItem {
let title: String
let textColor: UIColor
let selected: () -> Bool
let action: () -> Void
init(title: String,
textColor: UIColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1),
selected: @escaping () -> Bool = { return false },
action: @escaping () -> Void = { })
{
self.title = title
self.textColor = textColor
self.selected = selected
self.action = action
}
}
then the corresponding arguments are optional, for example:
let settingsItem = SettingsItem(title: "Title", selected: { return true })
Initialization of an inferred closure argument
If you can add #[derive(Default)]
to your structs, then this works:
// Create an instance of `T` and invoke a closure to initialize its fields.
// Allows creating a `T` without naming it, provided it is used in a context
// that accepts a concrete type. For example:
//
// hello_1(init(Default::default(), |v| v.id = 42));
fn init<T: Default>(mut v: T, f: impl FnOnce(&mut T)) -> T {
f(&mut v);
v
}
macro_rules! call_with_props {
($f: path, $($name: ident, $value: expr),+) => {{
$f(init(Default::default(), |v| {
$(v.$name = $value;)*
}))
}}
}
Playground
Swift initialize a struct with a closure
The closure passed to the constructor modifies the given argument,
therefore it must take an inout-parameter and be called with &self
:
public struct Style {
public var test : Int?
public init(_ build:(inout Style) -> Void) {
build(&self)
}
}
var s = Style { (inout value : Style) in
value.test = 1
}
println(s.test) // Optional(1)
Note that using self
(as in build(&self)
) requires that all its
properties have been initialized. This works here because optionals
are implicitly initialized to nil
. Alternatively you could define
the property as a non-optional with an initial value:
public var test : Int = 0
Related Topics
How to Cast from Cftyperef to Axuielement in Swift
Swift Protocol Extension Implementing Another Protocol with Shared Associated Type
Facebook Graphrequest for Swift 5 and Facebook Sdk 5
Make Tabview Background Transparent
How to Create a Cocoapod with .Swift
Does Cocoa Connection Binding to Nstoolbaritem Prevent Deinitializing
Why Is Swift Counting This Grapheme Cluster as Two Characters Instead of One
Cocoa: Simulating Command+Tab in Cgevent
Avspeechrecognizer: Required Condition Is False: _Recordingtap == Nil Error in Swift3
How to Detect If The User Was Deleted from Firebase Auth
Convert/Wrap Swift Struct as Nsvalue for Caanimation Purposes
Vapor 3 Postgresql Crud Without Requests Http
Create an Array of Protocols with Constrained Associated Types
Cannot Get Newpassword to Generate Strong Password and Autofill