The following code produces two values as output. It's clear why it prints in func. But where does the 2nd value come from (null)?
func(){
print("in func");
}
void main() {
var x = func;
print(x());
}
Output:
in func
null
You treated Dart like a scripting language and as a result, you got puzzled. Treat Dart as a the real programming language it is and it will be crystal clear:
dynamic func() {
// ^-- "dynamic" was inserted by your compiler,
// to make up for the fact you failed to mention a return type
print("in func");
// this is inserted by your compiler, to make up for the
// fact that a non-void function failed to provide a return value:
return null;
}
void main() {
var x = func;
// so this first calls the function, which prints it's line
// and then it prints the functions return value, which is null.
print(x());
}
Be explicit when programming. Use the power this language gives you.
When in doubt, turn on analysis. It will tell you what I told you: you missed to explicitely state things and now the compiler has to cover for you. That makes it hard to see what actually happens. Don't be hard on future readers. One of them is you, 5 seconds from now. Make it easy for yourself and be explicit about what code is doing.
Related
For class I have to make a program that calculates the birthday problem
Now I'm having trying to learn kotlin at the same time and I'm having trouble with a little snippet of code:
val checkSet = mutableSetOf<Int>()
generateSequence{ Random.nextInt(n)}.forEach {
if(!checkSet.add(it)) {
return#outForeach
}
}
outForeach#
sum += checkSet.size
As you can see I'm trying to do this with an infinite sequence. Kotlin doesn't accept this as outForeach is an unresolved reference. But this doesn't work either:
val checkSet = mutableSetOf<Int>()
generateSequence{ Random.nextInt(n)}.forEach {
if(!checkSet.add(it)) {
return#forEach
}
}
sum += checkSet.size
This will just start the forEach loop again. Is there a way to implement something as a forEachUntil or so?
p.s. I'm aware that this looks a lot like this question: 'return' doesn't jump out of forEach in Kotlin It's just that I don't really get the answers and I don't know if its applicable here. Also a way to implement forEachUntil seems for me to be far more elegant
Alternatives you may want to consider instead of first:
using a simple while without body:
while (checkSet.add(Random.nextInt(n))); // <- that semicolon is required! otherwise you execute what is coming next within the while
using run with a label:
run outForeach#{
generateSequence{ Random.nextInt(n)}.forEach {
if(!checkSet.add(it)) {
return#outForeach
}
}
}
maybe also takeWhile might be helpful. In this specific case however it is surely not (as it would check against the checkSet and leave us with a sequence that isn't consumed... but if the condition would be different, it may make sense to consider something like take, takeWhile, takeLast, etc.):
generateSequence { Random.nextInt(n) }
.takeWhile(checkSet::add) // as said: for this specific condition it doesn't make sense...
.forEach { /* do nothing except consume the sequence */ } // the same values you added to the set would be available in this step of course
I think I found the solution myself:
val checkSet = mutableSetOf<Int>()
generateSequence{ Random.nextInt(n)}.first { !checkSet.add(it) }
sum += checkSet.size
Basically use the function first() and keep returning false until you want to get out of the loop. And just drop the return of the function first()
I'm trying to convert a lua bridge from Swift 2 to Swift 3. I am not the original author so there are aspects of the library I don't know very well and the original author seems not interested to continue working on the project. I have most of the conversion done but there remain one place I'm stuck and could not figure out. I've tried searching on SO and on the Internet but could not find anything that could help me solve the problem.
If anyone is interested in looking at the full source code, here is my fork of the project on github: https://github.com/weyhan/lua4swift (My changes is in the Swift3 branch)
Allow me setup the context to the error I'm stuck on. There is a Userdata class, specifically in the method userdataPointer<T>() -> UnsafeMutablePointer<T> the c function lua_touserdata returns the block address of userdata as a void * pointer type.
Original code written in Swift 2:
public class Userdata: StoredValue {
public func userdataPointer<T>() -> UnsafeMutablePointer<T> {
push(vm)
let ptr = lua_touserdata(vm.vm, -1)
vm.pop()
return UnsafeMutablePointer<T>(ptr)
}
public func toCustomType<T: CustomTypeInstance>() -> T {
return userdataPointer().memory
}
public func toAny() -> Any {
return userdataPointer().memory
}
override public func kind() -> Kind { return .Userdata }
}
After the conversion with Xcode 8 migration tool, Xcode is complaining about the return line with error Cannot invoke initializer for type 'UnsafeMutablePointer<T>' with an argument list of type '(UnsafeMutableRawPointer?)':
return UnsafeMutablePointer<T>(ptr)
I've fixed it with:
return (ptr?.assumingMemoryBound(to: T.self))!
Following that above change, now Xcode 8 is now complaining about the calling statement in createCustomType:
public func createCustomType<T: CustomTypeInstance>(setup: (CustomType<T>) -> Void) -> CustomType<T> {
lua_createtable(vm, 0, 0)
let lib = CustomType<T>(self)
pop()
setup(lib)
registry[T.luaTypeName()] = lib
lib.becomeMetatableFor(lib)
lib["__index"] = lib
lib["__name"] = T.luaTypeName()
let gc = lib.gc
lib["__gc"] = createFunction([CustomType<T>.arg]) { args in
let ud = args.userdata
// ******* Here's the line that is causing problem in Swift 3
(ud.userdataPointer() as UnsafeMutablePointer<Void>).destroy()
// *******
let o: T = ud.toCustomType()
gc?(o)
return .Nothing
}
if let eq = lib.eq {
lib["__eq"] = createFunction([CustomType<T>.arg, CustomType<T>.arg]) { args in
let a: T = args.customType()
let b: T = args.customType()
return .Value(eq(a, b))
}
}
return lib
}
Where I'm getting stuck is the line :
(ud.userdataPointer() as UnsafeMutablePointer<Void>).destroy()
I believe the original author is attempting to clear the memory block where the pointer returned by userdataPointer() call is pointing to.
With the Xcode 8 auto migration tool the above line is converted as below:
(ud.userdataPointer() as UnsafeMutableRawPointer).deinitialize()
However Xcode now is then complains that Cannot convert call result type 'UnsafeMutablePointer<_>' to expected type 'UnsafeMutableRawPointer'.
From my research, the change to the return line in userdataPointer seems correct, so I think the issue is with the cast to UnsafeMutableRawPointer. I've tried dropping the cast to UnsafeMutableRawPointer and invoke ud.userdataPointer().deinitialize() directly but I get this error Generic parameter 'T' could not be inferred.
Other things I've tried is to convert the UnsafeMutablePointer to UnsafeMutableRawPointer but It always result in Xcode 8 complaining one thing or another. Any suggestion on how to get this to work?
As you may have already found out, Swift 3 attempts to provide better type safety when it comes to pointers. UnsafeMutablePointer can now only represent a pointer to an instance of a known type. In Swift 2, a C void * was represented by UnsafeMutablePointer<Void>, allowing void and non-void pointers to be treated in the same way, including trying to call a de-initializer of the pointed-to type, which is what the destroy() method in the problematic line of code does:
(ud.userdataPointer() as UnsafeMutablePointer<Void>).destroy()
In Swift 3 the de-initializer on the pointee is called using the deinitialize() method of the UnsafeMutablePointer structure. It appears that the migration assistant got confused. The line
(ud.userdataPointer() as UnsafeMutableRawPointer).deinitialize()
makes little sense because (1) UnsafeMutablePointer cannot be converted using as to UnsafeMutableRawPointer;
(2) UnsafeMutableRawPointer has not deinitialize() method. In Swift 3, UnsafeMutableRawPointer is a special type to represent void*. It is actually quite understandable why the migration tool made this mistake: it blindly replaced destroy() with deinitialize() and UnsafeMutablePointer<Void> with the corresponding Swift 3 type UnsafeMutableRawPointer, without realizing that the conversion would not work.
I don't quite understand why calling destroy() on a void pointer would work in Swift 2. Maybe this was a bug in the program or some compiler trick allowed the correct de-initializer to be called. Without knowing enough about the code, I can't be more specific than to suggest analyzing it to figure out what is the type pointed to by that pointer on which destroy() was called. For example, if we know for sure that it is always the placeholder type T used on the following line:
let o: T = ud.toCustomType()
then the offending line simply becomes
(ud.userdataPointer() as UnsafeMutablePointer<T>).deinitialize()
We need the conversion in the parentheses to allow the compiler to infer the generic parameter.
Thank you for bringing up an interesting problem. BTW, once you get over this obstacle, you are likely to run into other problems. One thing that jumps out is that UnsafeMutablePointer has no .memory in Swift 3; you'll have to use .pointee instead.
Here's an update. After playing with Swift 2.2 on Linux, I realize that calling destroy() on an UnsafeMutablePointer<A> cast as UnsafeMutablePointer<Void> won't call A's deinitializer, even if it has one. So, you have to be careful with that line...
Try creating an instance of UnsafeMutableRawPointer instead of trying to cast it:
UnsafeMutableRawPointer<T>(ud.userdataPointer()).destroy()
i am developing an ea that requires me to compare the high of previous 2 bars and whichever one is higher, use that as a stop loss value.
same for opposite side trades, i need to compare previous 2 lows and use the lower one as stop loss value.
what i am doing is this:-
void onTick()
{
static int ticket=0;
double ab=(//calculation for ab);
double de=(//calculation for de);
if(Low[1]<Low[2])
double sll=Low[1];
if(Low[1]>Low[2])
double sll=Low[2];
if(buy logic comes here)
{
double entryPrice=////////;
double stoploss=sll-xyz;
double takeprofit=entryPrice+((entryPrice-stoploss)*3);
ticket = OrderSend(Symbol(),...entryPrice,stoploss,takeprofit,.....);
}
if(ticket == false)
{
Alert("Order Sending Failed");
}
}
the problem is i am not able to reference the values of sll and get an error message saying "sll undeclared identifier"
i am fairly new to programming and would appreciate if someone can help me out with this.
I have added most of the code for you to understand the logic.
you would have to declare them outside the scope of the if statements if you want to use variables anywhere else so instead of doing that take a look at this
double sll; // declare sll outside the if statements
if(Low[1]<Low[2])
sll=Low[1];
if(Low[1]>Low[2])
sll=Low[2];
if(buy logic comes here)
{
bool res = OrderSend(..........);
}
Judging by what you wrote, it looks like you may be using res somewhere else too which then you need to define outside of the if statement because scoping.
I want to run different functions depending on selected level Integer
so if selected level is 1 then runfunc1(), if 2 then runfunc2()...
I know this is possible using if else
if levelselected == 1 {
runfunc1()
} else if levelseletecd == 2 {
runfunc2()
// ... and so on
}
Is there any better way than this, perhaps something like this
runfunc%i(),levelselected // I know its not correct but something similar
I dont want to write new code for every level, so any better way?
You can use something like:
var levelSelected = 0 //
var selector = Selector("runFunc\(levelSelected)")
if self.respondsToSelector(selector) {
NSThread.detachNewThreadSelector(selector, toTarget: self, withObject: nil)
}
You could have an array or dictionary of functions. A dictionary might be nicer since the logic for checking if the level is valid is a lot simpler:
let funcs = [1: runfunc1, 2: runfunc2]
if let funcToRun = funcs[levelselected] {
funcToRun()
}
However, you won't be able to easily dynamically build a function name from strings and numbers without using #objc functionality.
(except in the sense that you could make the key to the dictionary a string of the function name, but you still have to build the dictionary using actual function names determined at compile time)
That said, you can add to the funcs variable from elsewhere in the code so it does mean to can "hook up" new levels without changing this dispatching logic.
Not the exact solution you are looking for but this can make it easier :
Declare an array of the desired functions:
var levelFunctions: [()->()] = [runfunc1, runfunc2, runfunc3]
This syntax declares an array of functions that have zero argument and return nothing. You initialize this array with the required function names and then execute the desired function using the levelselected variable:
levelFunctions[levelselected]() // Or levelselected-1 if the variable is not zero-based
EDIT:
As Airspeed Velocity mentioned in the comment and his answer you should make sure the level is in the array bounds.
I prefer to create a function, for example runFuncFromLevel::Int -> (() -> Void). runFuncFromLevel return a proper function that you need.
func runFuncFromLevel(level: Int) -> () -> Void
{
switch level
{
case 1: return runfunc1
case 2: return runfunc2
default: return {}
}
}
Below is some code I wrote:
func Begin(input: String) -> Double {
let inputs = (input as NSString).lowercaseString
var smth = AnalyzeInput(input: inputs)
return smth.findOutput()
}
Line 3 of this code (the 'smth' declaration) begins a long series of code that, at many instances, may throw some kind of an error (typically an index out of bounds error when creating a substring). Because this code is about 5,000 lines in 15 different files, and manually handling each exception would take a long time for each one, I would greatly prefer to not have to manually handle these exceptions.
I understand that there is no try / catch / finally structure in Swift, but is there anything where I can mimic that functionality? Or did I just dig myself into a giant hole?
If you're throwing exceptions in cases that are not catastrophic errors (i.e. you expect to crash soon), then you've dug yourself a hole. Cocoa does not use exceptions for general error handling. It uses them for truly exceptional situations. It's up to you to avoid index-out-of-bounds.
See the Error Handling Programming Guide for Cocoa for documentation on Cocoa error handling. Your function should likely look something like this:
func begin(input: String, error: NSErrorPtr) -> Double? {
let inputs = input.lowercaseString // "as NSString" is no longer needed
let smth = AnalyzeInput(input: inputs, error: NSErrorPtr) // pass along your error pointer
return smth?.findOutput() // Use ?. to return nil if smth is nil, or Double? otherwise
}
Some of us are exploring more functional approaches, such as a Result object. These are all still pretty experimental, but in principle it would look like this:
func begin(input: String) -> Result<Double, NSError> {
let inputs = input.lowercaseString
let smth = AnalyzeInput(input: inputs) // AnalyzeInput would return a Result
return smth.map { $0.findOutput() } // And then we map it to the final result
}