Hmm, well.. a struct is really just a way to bundle up data. For instance, in your case you want to make a spell which uses a number of different variables. One way to solve this is to make an array for each variable, and then some way keep track of a unique ID for each spell instance which you can use as index. Let's say we have an effect dummy named "u", which has an id named "id", we can do it like this with pure jass:
set udg_effectX[id] = GetUnitX(u)
set udg_effectY[id] = GetUnitY(u)
set udg_timeLeft[id] = 10
....etc. Now, if we want to pass data from one function to another, say using a timer, we only need to pass the ID of the effect to access all the data. But this solution is a bit ugly - we need to write out the index for every single variable even though we only want to work on one specific instance. Structs work on this exact same principle, but they work to "hide" this ugliness from you. This is how a basic struct can look:
JASS:
struct MySpell
real effectX
real effectY
real timeLeft
unit effectDummy
effect effectArt
static method create takes real x, real y, real time, integer dummyid, string effectpath returns MySpell
local MySpell this = MySpell.allocate() //The "allocate" function gives our struct a unique index. "this" marks the current instance.
set .effectX = x //Once we have defined "this", we can access it's member variables using for example "this.effectX".
set .effectY = y //However, we don't actually need to write "this" for the compiler to understand. I usually place a singe dot in front of the variable to
set .timeLeft = time //Signify that it is a member of the struct and not some local variable
//....and the same for all variables we want to initialize
return this //Every "create" method must return an instance of the struct!
endmethod
endstruct
Now, we can just do this:
JASS:
local MySpell somename = MySpell.create(0, 0, 10, 'dumm', "effect.mdl")
set somename.timeLeft = 4 //We can access members like this, using a dot between the instance name and the variable name.
Now you might be wondering, what is a method? And what does "static" mean?
A method is just a function which is associated to your struct. Usually it is a function which somehow manipulates the variables you have defined. Let's say you have a struct named "missile", and you want to add some kind of functionality to it. One thing you might want is a method called "explode", in which you code whatever will happen when it explodes. Another might be "bounce", in which the missile bounces on the terrain.
"static" means that the method works like a normal function, which is not associated to any specific instance. This means that the "this" variable is not automatically set. However, you can create a local variable named "this" inside the method and set it to something, and then you can acces the member variables in the same way as you are used to. You need to use static methods if you want to use them as a trigger action, or as a function that runs upon timer expiration (as theese need to take nothing and return nothing whereas regular methods take the struct index, even though you cannot see it).
On important thing to remember is to destroy the struct once you are done with it. This you do using "instancename.destroy()". If you don't destroy your struct instances, the index will not be recycled, and you will eventually run out of indexes. This will prevent new structs from being created.
A destroy method is automatically created for each struct, but you can link a kind of trigger action to the struct destroy event by defining a method named "onDestroy". This is useful if you want some stuff to be cleaned up as the struct is destroyed. Be mindful though that it uses some stuff which might reduce performance ever so slightly, so it is not recommended for heavier stuff such as projectile system. I recommend reading the jasshelper manual if you want to know more about this.
Ugh, i am really tired and might have confused more than i infored. Hope it helped somewhat though, otherwise just read the toturials which IcemanBo linked.
EDIT: as a side note, items and units in warcraft can be seen as structs. They have some variables inside them, such as life, mana, fly height etc, and there are functions you can use to manipulate them (even though you don't use the dot operator to do so). For instance you can use use GetUnitX() to get the X coordinate. As a struct, units would look kinda like this:
JASS:
struct unit //Don't try to use "unit" as a struct name, i am just doing it to demonstrate.
real x
real y
real health
real mana
real flyheight
method GetUnitFlyHeight takes nothing returns real //Same with these function names.
return .flyheight
endmethod
method GetUnitX takes nothing returns real
return .x
endmethod
method GetUnitY takes nothing returns real
return .y
endmerthod
method SetUnitFlyHeight takes real height returns nothing
set .flyheight = height
endmethod
endstruct
function TestFunction takes nothing returns nothing
local unit u = unit.create() //We create an instance. Note that it is not legal to call a struct "unit", i just do it to demonstrate the similarities between structs and built-in classes.
local real x = u.GetUnitX()
local real y = u.GetUnitY()
call u.SetUnitFlyHeight(100)
call u.destroy() //Clean up. This is kinda like removing leaks.
endfunction