is there is a way to negate the "if let" in swift?
This looks silly to me:
if let type = json.type {
} else {
XCTFail("There is no type in the root element")
}
I can't use XCTAssertNotNil, because json.type is a enum.
enum JSONDataTypes {
case Object
case Array
case Number
case String
}
Thanks a lot
EDIT: it is a:
var type: JSONDataTypes? = nil
Swift 2.0 (Xcode 7) and later have the new guard statement, which sort of works like an "if not let" -- you can conditionally bind a variable in the remainder of the enclosing scope, keeping the "good path" in your code the least-indented.
guard let type = json.type else {
XCTFail("There is no type in the root element")
}
// do something with `type` here
The catch to this is that the else clause of a guard must exit that scope (because otherwise you'd fall into code after that clause, where the guarded variables, like type above, are unbound). So it has to end with something like return, break, continue or a function that is known to the compiler to never return (i.e. annotated #noreturn, like abort()... I don't recall offhand if that includes XCTFail, but it should (file a bug if it's not).
For details, see Early Exit in The Swift Programming Language.
As for really-old stuff... There's no negated form of if-let in Swift 1.x. But since you're working with XCTest anyway, you can just make testing the optional part of an assertion expression:
XCTAssert(json.type != nil, "There is no type in the root element")
Here's how you do it:
if json.type == nil {
// fail
}
Another alternative I've used a few times:
switch json.type
{
case .None: // ...
case .Some(.Object): // ...
case .Some(.Array): // ...
case .Some(.Number): // ...
case .Some(.String): // ...
}
Since the ? is actually Optional<T> which is an enum on its own, defined as:
enum Optional<T> : Reflectable, NilLiteralConvertible
{
case None
case Some(T)
...
}
Related
I am issuing calls that return an Option that contains a Result which contains another Option that contains custom variants.
I am only ever interested in a specific chain of variant results like this:
if let Some(Ok(Some(CustomVariant(Some(value))))) = expr {
// handle value case
}
This is getting quite verbose and not really helpful, since I actually treat it as a single Result in all of my code. Can I somehow alias this code so that instead of writing the entire chain of Options and Results I can do something similar to:
alias TheCase(value) = Some(Ok(Some(CustomVariant(Some(value))));
if let TheCase(value) = expr {
//handle value
}
You don't need such an alias, just use a function to retrieve the one case you want:
fn oneCaseICareAbout(value: &Option<Result<Option<Foo>, Bar>>) -> Option<&Foo> {
if let Some(Ok(Some(CustomVariant(Some(value)))) = value {
Some(value)
} else {
None
}
}
if let Some(value) = oneCaseICareAbout(expr) {
//handle value
}
I would however consider refactoring your code not to use such a type. Option<Result<_, _>> is already a red flag, but Some(Ok(Some(CustomVariant(Some(…)))) is just on the edge of insanity!
What is the Perl 6 way to tell the difference between an argument and no argument in a block with no explicit signature? I don't have any practical use for this, but I'm curious.
A block with no explicit signature puts the value into $_:
my &block := { put "The argument was $_" };
The signature is actually ;; $_? is raw. That's one optional argument. The #_ variable isn't defined in the block because there is no explicit signature.
There's the no argument, where $_ will be undefined:
&block(); # no argument
But there's also a one argument situation where $_ will be undefined. A type object is always undefined:
&block(Int);
But, an $_ with nothing in it is actually an Any (rather than, say, Nil). I can't tell the difference between these two cases:
&block();
&block(Any);
Here's a longer example:
my $block := {
say "\t.perl is {$_.perl}";
if $_ ~~ Nil {
put "\tArgument is Nil"
}
elsif ! .defined and $_.^name eq 'Any' {
put "\tArgument is an Any type object"
}
elsif $_ ~~ Any {
put "\tArgument is {$_.^name} type object"
}
else {
put "\tArgument is $_";
}
};
put "No argument: "; $block();
put "Empty argument: "; $block(Empty);
put "Nil argument: "; $block(Nil);
put "Any argument: "; $block(Any);
put "Int argument: "; $block(Int);
Notice the no argument and Any argument forms show the same things:
No argument:
.perl is Any
Argument is an Any type object
Empty argument:
.perl is Empty
Argument is Slip type object
Nil argument:
.perl is Nil
Argument is Nil
Any argument:
.perl is Any
Argument is an Any type object
Int argument:
.perl is Int
Argument is Int type object
As far as I know, the only way to know the number of parameters passed without an explicit signature, is to use #_ inside the body, which will generate a :(*#_) signature.
my &block := { say "Got #_.elems() parameter(s)" };
block; # Got 0 parameter(s)
block 42; # Got 1 parameter(s)
dd block.signature; # :(*#_)
Yeah, the good old #_ is still there, if you want it :-)
{ put $_.perl }
Is sort of similar to this: (which doesn't work)
-> ;; $_? is raw = CALLERS::<$_> { put $_.perl }
Since the default is default for $_ outside of the block is Any, if you don't place anything into $_ before you call the function you get Any.
To get something at all similar where you can tell the difference use a Capture :
my &foo = -> ;; |C ($_? is raw) {
unless C.elems {
# pretend it was defined like the first Block above
CALLER::<$_> := CALLER::CALLERS::<$_>
}
my $called-with-arguments := C.elems.Bool;
if $called-with-arguments {
say 'called with arguments';
} else {
say 'not called with arguments';
}
}
Here's how I solved this. I'd love to do this in a cleaner way but the cleverness of the language gets in the way and I have to work around it. This works for positional parameters but there are deeper shenanigans for named parameters and I won't deal with those here.
I had another question, Why does constraining a Perl 6 named parameter to a definite value make it a required value?, where the answers clarified that there are actually no optional parameters. There are merely parameters that have a default value and that there is an implicit default value if I don't explicitly assign one.
The crux of my problem is that I want to know when I gave the parameter a value and when I didn't. I give it a value through an argument or an explicit default. An implicit default is a type object of the right type. That's Any if I didn't specify a type. That implicit default must satisfy any constraint I specify.
The first goal is to tightly constrain the values a user can supply when they call code. If an undefined value is not valid then they shouldn't be allowed to specify one.
The second goal is to easily distinguish special cases in the code. I want to reduce the amount of special knowledge some part of the deeper code needs to know.
I can get the third case (where I know there was no argument or suitable default) by explicitly assigning a special value that I know can't be anything other meaningful thing. There's a value that's even more meaningless than Any. That's Mu. It's the most undefined values of all undefined values. The Any is one of two subtypes of Mu (the other is Junction) but you should almost never see a Mu end up in one of your values in normal code. Undefined things in user code start at Any.
I can create a constraint that checks for the type I want or for Mu and set a default of Mu. If I see a Mu I know there was no argument and that it's Mu because my constraint set that.
Since I'm using Mu there are some things I can't do, like use the === operator. Smart matching won't work because I don't want to test the inheritance chain. I can check the object name directly:
my $block := ->
$i where { $^a.^name eq 'Mu' or $^a ~~ Int:D } = Mu
{
say "\t.perl is {$i.perl}";
put do given $i {
when .^name eq 'Mu' { "\tThere was no argument" }
when Nil { "\tArgument is Nil" }
when (! .defined and .^name eq 'Any') {
"\tArgument is an Any type object"
}
when .defined {
"\tArgument is defined {.^name}"
}
default { "\tArgument is {.^name}" }
}
};
put "No argument: "; $block();
put "Empty argument: "; try $block(Empty); # fails
put "Nil argument: "; try $block(Nil); # fails
put "Any type argument: "; try $block(Any); # fails
put "Int type argument: "; try $block(Int); # fails
put "Int type argument: "; $block(5);
Now most of those invocations fail because they don't specify the right things.
If these were routines I could make multis for a small number of cases but that's an even worse solution in the end. If I had two parameters I'd need four multis. With three such parameters I'd need six. That's a lot of boilerplate code. But, blocks aren't routines so that's moot here.
When I was sifting through some of the class discussions for AVFoundation, I stumbled upon the following:
class func defaultDeviceWithMediaType(mediaType: String!) -> AVCaptureDevice!
Because optionals are a new concept to me, I'm a bit confused.
The discussion says that this method could either return "the default device with the given media type, or nil if no device with that media type exists." However, if there is a possibility that it's returning nil, why do they unwrap this optional in the return statement? Shouldn't it be AVCaptureDevice?
Then, when looking at an example that utilizes the above method, I find the following:
public lazy var device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
public func hasFlash() -> Bool {
if let d = self.device {
return d.hasFlash
}
return false
}
From what I understand, you would use an if let statement when you have an optional, but because the class defaultDeviceWithMediaType returns an unwrapped variable, why is having an if let necessary?
Thank you so much in advance.
Implicitly unwrapped optional is basically an optional, that gets an ! everywhere you use it. Thats it.
e.g.:
//this:
var number: Int? = ...
print(number!)
//is the same as this:
var number: Int! = ...
print(number)
An implicitly unwrapped optional is only to save you the need of unwrapping it every time you use it, wether with if let or with an !, but it has the same optionality of being nil as a normal optional.
A popular use of Implicitly unwrapped optionals is with outlets - they can't be non-optionals because we don't init them in the init of the VC, but we definitely have them later, so having them unwrapped saves us the need to do annoying things like if let table = self.tableView....
An implicitly unwrapped optional is still an optional - it could be nil. If you simply write self.device.hasFlash, when self.device is nil, you will get an exception.
I was building a custom UI and I realize that for some reason I cannot do this.
protocol notImportant{
SegementButtons(segmentControl : VerticalSegmentControl) -> Int
}
//trying to use the function later in this fashion below
for index in 0...delegate?.segementButtonsCount(self)
Now I know there are many other solutions.
First of all, is this valid or must I provide a concrete number or variable?
Continued
Xcode shows an error
Binary operator '...' cannt be applied to oraands of type Int and Int?
I type cast the return value to an Int, changing the error to
Type Int does not conform to protocol SequenceType
Now it would be pretty cool if I could make this work without Xcode cutting itself.
delegate is an optional, therefore the type of the expression
delegate?.segmentButtonsCount(self)
is also an optional (which is nil if delegate == nil).
You can use optional binding to unwrap the delegate
if let theDelegate = delegate {
for index in 0 ..< theDelegate.segmentButtonsCount(self) {
// do something ...
}
}
or use the nil-coalescing operator ?? to provide a
default value:
for index in 0 ..< (delegate?.segmentButtonsCount(self) ?? 0) {
// do something ...
}
Note that since array indices are zero-based, you probably want to use the range operator ..< which
excludes the end element.
I have an Query expression that uses a predicate type and lambda expression.
I am getting desired result with this. But I am not clear with how this expression is getting evaluated.
I tried to break this lambda expression by creating delegate and replacing condition under Where with delegate type.
If I have to rewrite the same thing with writing a delegate instead of anonymous type. What will be the syntax. How the delegate will be return for the same.
if (((DataTable)dgvAssignedRpm.DataSource).AsEnumerable()
.Where(row => row.Field<long>("FK_RPM_BTN_SETTING_ID") == objRpmButtonHolder.RpmSettingId).Count() > 1)
{
List<DataRow> listPkgBtnSettings = SearchForExistingSettingId();
}
void MethodSignature(...)
{
...
if (((DataTable)dgvAssignedRpm.DataSource).AsEnumerable()
.Where(RowCondition)
{
List<DataRow> listPkgBtnSettings = SearchForExistingSettingId();
}
...
}
// Where want a Func<T,bool> parameter
// T is the first parameter type (DataRow here)
// bool represents the return value
bool RowCondition(DataRow row)
{
return row.Field<long>("FK_RPM_BTN_SETTING_ID") == objRpmButtonHolder.RpmSettingId).Count() > 1
}
I assume the correct delegate replacement would be:
if (((DataTable)dgvAssignedRpm.DataSource).AsEnumerable().Where(
delegate(DataRow row) {
return (row.Field<long>("FK_RPM_BTN_SETTING_ID") == objRpmButtonHolder.RpmSettingId.Count() > 1);
}))
{
List<DataRow> listPkgBtnSettings = SearchForExistingSettingId();
}
But it's morning for me, so forgive me if I'm a bit off.
What the where desires is to give a DataRow as a parameter and a bool to return. You could just about fill in anything in the lambda or delegate, as long as it matches these requests.
To your question why it requests Func<> and how it works. The statement you're using is LINQ, so I found you a reference regarding this which can probably explain it better than me:
http://blogs.msdn.com/b/mirceat/archive/2008/03/13/linq-framework-design-guidelines.aspx
But yeah, the last type here in the Func<> is what it returns. (However, I can still recommend using the Lambda expression, as it's pretty clean, neat and serves the Func<> best.
(Also, look at what intellisence gives you when you write "new Func<....", it should give you a good idea of what Func wants and can do!)
Hope I was of help.