My Code:
void main() {
String name() {
return "Uday Kiran";
}
void printF(var value) {
print(value);
}
printF(name);
}
Hey, I'm sorry if my question is silly. But I'm probably new to the programming and I stuck by doing something like this. I actually wanted to pass the string returned by the name function, as a argument to my printF function, so that the string "Uday Kiran" would be printed on my console. But the output I get is something like this:
Any help would be appreciable:)
The problem is that you are refer to name as a variable which points to a Function instead of calling the function it points to. In Dart, you call a function with () (in case of no arguments) so your example should instead be:
void main() {
String name() {
return "Uday Kiran";
}
void printF(String value) {
print(value);
}
printF(name());
}
I also changed the type of argument to specify you want to get a String as argument as stated in your question. By doing so, you would also got an error explaining the problem with name in your example.
Related
Is there a way to return several values in a function return statement (other than returning an object) like we can do in Go (or some other languages)?
For example, in Go we can do:
func vals() (int, int) {
return 3, 7
}
Can this be done in Dart? Something like this:
int, String foo() {
return 42, "foobar";
}
Dart doesn't support multiple return values.
You can return an array,
List foo() {
return [42, "foobar"];
}
or if you want the values be typed use a Tuple class like the package https://pub.dartlang.org/packages/tuple provides.
See also either for a way to return a value or an error.
I'd like to add that one of the main use-cases for multiple return values in Go is error handling which Dart handle's in its own way with Exceptions and failed promises.
Of course this leaves a few other use-cases, so let's see how code looks when using explicit tuples:
import 'package:tuple/tuple.dart';
Tuple2<int, String> demo() {
return new Tuple2(42, "life is good");
}
void main() {
final result = demo();
if (result.item1 > 20) {
print(result.item2);
}
}
Not quite as concise, but it's clean and expressive code. What I like most about it is that it doesn't need to change much once your quick experimental project really takes off and you start adding features and need to add more structure to keep on top of things.
class FormatResult {
bool changed;
String result;
FormatResult(this.changed, this.result);
}
FormatResult powerFormatter(String text) {
bool changed = false;
String result = text;
// secret implementation magic
// ...
return new FormatResult(changed, result);
}
void main() {
String draftCode = "print('Hello World.');";
final reformatted = powerFormatter(draftCode);
if (reformatted.changed) {
// some expensive operation involving servers in the cloud.
}
}
So, yes, it's not much of an improvement over Java, but it works, it is clear, and reasonably efficient for building UIs. And I really like how I can quickly hack things together (sometimes starting on DartPad in a break at work) and then add structure later when I know that the project will live on and grow.
Create a class:
import 'dart:core';
class Tuple<T1, T2> {
final T1 item1;
final T2 item2;
Tuple({
this.item1,
this.item2,
});
factory Tuple.fromJson(Map<String, dynamic> json) {
return Tuple(
item1: json['item1'],
item2: json['item2'],
);
}
}
Call it however you want!
Tuple<double, double>(i1, i2);
or
Tuple<double, double>.fromJson(jsonData);
You can create a class to return multiple values
Ej:
class NewClass {
final int number;
final String text;
NewClass(this.number, this.text);
}
Function that generates the values:
NewClass buildValues() {
return NewClass(42, 'foobar');
}
Print:
void printValues() {
print('${this.buildValues().number} ${this.buildValues().text}');
// 42 foobar
}
The proper way to return multiple values would be to store those values in a class, whether your own custom class or a Tuple. However, defining a separate class for every function is very inconvenient, and using Tuples can be error-prone since the members won't have meaningful names.
Another (admittedly gross and not very Dart-istic) approach is try to mimic the output-parameter approach typically used by C and C++. For example:
class OutputParameter<T> {
T value;
OutputParameter(this.value);
}
void foo(
OutputParameter<int> intOut,
OutputParameter<String>? optionalStringOut,
) {
intOut.value = 42;
optionalStringOut?.value = 'foobar';
}
void main() {
var theInt = OutputParameter(0);
var theString = OutputParameter('');
foo(theInt, theString);
print(theInt.value); // Prints: 42
print(theString.value); // Prints: foobar
}
It certainly can be a bit inconvenient for callers to have to use variable.value everywhere, but in some cases it might be worth the trade-off.
Dart is finalizing records, a fancier tuple essentially.
Should be in a stable release a month from the time of writing.
I'll try to update, it's already available with experiments flags.
you can use dartz package for Returning multiple data types
https://www.youtube.com/watch?v=8yMXUC4W1cc&t=110s
you can use Set<Object> for returning multiple values,
Set<object> foo() {
return {'my string',0}
}
print(foo().first) //prints 'my string'
print(foo().last) //prints 0
In this type of situation in Dart, an easy solution could return a list then accessing the returned list as per your requirement. You can access the specific value by the index or the whole list by a simple for loop.
List func() {
return [false, 30, "Ashraful"];
}
void main() {
final list = func();
// to access specific list item
var item = list[2];
// to check runtime type
print(item.runtimeType);
// to access the whole list
for(int i=0; i<list.length; i++) {
print(list[i]);
}
}
I noticed that i can set a return type on a function to 'Void' aswell as 'void' and just wondered if there was and benefit of either?
Void (with uppercase "v") was ActionScript 2 version of ActionScript 3 void.
AS3 docs (void):
Specifies that a function cannot return any value. The void type is a special type that contains exactly one value: undefined. It is special in that its use is limited to the return type of a function. You cannot use void as a type annotation for a property.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/specialTypes.html#void
AS2 docs (Void):
The Void data type has one value, void, and is used in a function definition to indicate that the function does not return a value, as shown in the following example:
//Creates a function with a return type Void
function displayFromURL(url:String):Void {}
http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00000037.html
No there isn't. void type just says the compiler that no value will be returned.
void type indicates to the compiler that the function you have written will not return any value, in the other side if you indicate other type int than void the compiler expect that you return int.
Ex:
function foo(a:int):int
{
// here the compiler expect that somewhere
// in your function you return an int
return a;
}
AS2 = :Void
AS3 = :void
Is there any way to get an object by it's UID so that the following code would work?
When the function finishes, the value of property "xxx" should be "string two" not "string one".
// Test class
public function test():void {
this.xxx = "string one";
foo.bar(this.xxx);
trace(this.xxx); // Prints: string two
}
// Foo class
public function bar(value:*):void {
// ... What would I have to do here to get the property, not its value?
value = "string two";
}
What about using the Box brackets? I know this is not the OO way of doing the thing but Action script supports it and it looks like a good alternative here.
class Test {
public var xxx:String;
public function test():void {
this.xxx = "string one";
foo.bar(this,"xxx"); // actual name of property as string ;litral
trace(this.xxx); // Prints: string two
}
}
class Foo {
public function bar(test:*,prop:String):void {
//test could be from any class .
test[prop] = "string two";
}
}
This should do the trick. But You need to make sure whichever code calls "bar" method passes a valid object which has "xxx" property defined as this code is not type safe any more.
A function's parameter (a reference to a variable) can't be changed. It's not a pointer. You can assign other variables to it, but it won't change the argument passed to that function. But you can change the argument's properties:
class Test {
public var xxx:String;
public function test():void {
this.xxx = "string one";
foo.bar(this);
trace(this.xxx); // Prints: string two
}
}
class Foo {
public function bar(test:Test):void {
test.xxx = "string two";
}
}
Of course for this to work, the class Foo has to know Test and also which property to change. This makes everything less dynamic and is maybe not what you want. It's a case where you could use an Interface. Or you might want to stick to common patterns like using a getter and assigning the value to the appropriate property:
class Test {
public var xxx:String;
public function test():void {
this.xxx = "string one";
this.xxx = foo.getValue();
trace(this.xxx); // Prints: string two
}
}
class Foo {
public function getValue():String{
return "string two";
}
}
To get to a property, the easiest way is to encapsulate the property into an object, pass it to the function, and then retrieve it:
// Test class
public function test():void {
var obj: Object = new Object();
obj.variable = "string one";
foo.bar(obj);
trace(obj.variable); // Prints: string two
}
// Foo class
public function bar(value:Object):void {
value.variable = "string two";
}
But why would you want to do this? It's much better in every way to just do xxx = foo.bar();
Pass-by-value:
When passing a variable into a function the variable is copied. Any changes you make to the variable aren't reflected back once you exit.
Pass-by-reference:
When passing a variable into a function, the "pointer" to the variable is passed. Any changes you make to the variable are copied over.
In AS3, everything is pass-by-reference, except primitives (Boolean, String, int, uint, etc), which have special operators behind the scenes to make them act like pass-by-value. As xxx is a String, this is what's happening. (Also, Strings are immutable; you can't actually change their value).
How to fix it (as others have said):
Pass the Test object itself to the bar() function: bar( this );
Encapsulate the xxx parameter in it's own object and pass that: bar( {prop:this.xxx} );
Have bar() return the value and set it: this.xxx = bar();
Is there any way, given a function variable, to get the name of the function as a string? For example, if I have:
void function(int) func;
Is there some function x() such that I could get:
x(func) == "func";
? I feel like this would be possible using mixins, but I'm confused as to how to implement this.
func.stringof
is what you need.
You could also make a template:
template Name(alias Func) { enum Name = Func.stringof; }
void func() { }
pragma(msg, Name!(func)); //prints func()
Simplest solution that comes to my mind:
You can have its name stored in a string, and mixin'ed where necessary, something like:
string func_name = "func";
...
int param = 294;
mixin(func_name ~ "(" ~ to!string(param) ~ ")");
I am able to get the signature and arguments from advised method calls, but I cannot figure out how to get the return values or exceptions. I'm kind of assuming that it can be done in some way using around and proceed.
You can use after() returning and after() throwing advices as in beginning of the following document. If you're using #AspectJ syntax please refer to #AfterReturning and #AfterThrowing annotations (you can find samples here).
You can also get return value using after returing advice.
package com.eos.poc.test;
public class AOPDemo {
public static void main(String[] args) {
AOPDemo demo = new AOPDemo();
String result= demo.append("Eclipse", " aspectJ");
}
public String append(String s1, String s2) {
System.out.println("Executing append method..");
return s1 + s2;
}
}
The defined aspect for getting return value:
public aspect DemoAspect {
pointcut callDemoAspectPointCut():
call(* com.eos.poc.test.AOPDemo.append(*,*));
after() returning(Object r) :callDemoAspectPointCut(){
System.out.println("Return value: "+r.toString()); // getting return value
}
Using an around() advice, you can get the return value of the intercepted method call by using proceed(). You can even change the value returned by the method if you want to.
For instance, suppose you have a method m() inside class MyClass:
public class MyClass {
int m() {
return 2;
}
}
Suppose you have the following aspect in its own .aj file:
public aspect mAspect {
pointcut mexec() : execution(* m(..));
int around() : mexec() {
// use proceed() to do the computation of the original method
int original_return_value = proceed();
// change the return value of m()
return original_return_value * 100;
}
}